Skip to content
Fabian Homborg edited this page Jan 6, 2021 · 13 revisions

Commits

  1. Any changes must conform to the style guide. This is true for the core C++ code as well as the fish script files that are part of the core distribution. You can run make style to ensure your changes conform to the style guide. For C++ code this is done with clang-format. For fish scripts it is done with fish_indent.

  2. If a commit fixes an issue, reference that issue in the commit message. For example:

    Output embedded null characters more often
    https://github.com/fish-shell/fish-shell/issues/444
    

    or:

    Tweak the switch and case builtins to not blow away $status inappropriately. Fixes issue #161.
    

    If the fix is found to have caused problems and we have to revisit it, this will help us reproduce the original issues.

  3. If you fix an issue, move it to the current milestone. That is, tag it with the next milestone label.

  4. All non-trivial changes should be associated with an issue. If you make such a change, and there is not an issue for it yet, create an issue, move it to the current milestone, reference it in the commit. That should automatically close the issue when the commit is made but if it doesn't manually close it. Release notes are generated from the list of closed issues in the milestone.

  5. Do a pull --rebase before pushing your commits, so that history can be kept as linear as possible. For example:

    git commit -m "Replace a fixed size buffer with a std::string, preventing a buffer overflow. Fixes #456."
    git pull --rebase
    git push
    
  6. Avoid force-pushing to the master branch at almost all costs. Among other things, it breaks the nightly builds.

  7. Try and use one change per commit; see the Pro Git guidelines.

Merges

When merging a pull request, it is necessary to merge into trunk; i.e., the master branch. There are several merge types possible: a normal merge, a merge with rebase, or a squash merge. All of them produce the same code changes, but show different history in the repo. This is important for identifying which commits caused a regression, or why a particular line of code exists. A summary of the differences is:

  1. A normal merge will show that the code diverged into separate branches, and then later reunited. This is the "true" history, but may be confusing.
  2. A merge with rebase will show that the changes were all made on the tip of the trunk, so nothing ever diverged. This is a somewhat falsified history, but it keeps the history linear and understandable.
  3. A squash merge throws away the entire history of the branch, resulting in a single commit.

For more information refer to a book like Pro Git or Version Control With Git. I've purchased and read both of them. The former is free online but the latter is the better book on the topic of using Git.

The merge guidance is:

  1. Do a rebase for most branches or pull requests, if they are simple - contain only a few commits and touches only a few files. Here is an example:

    git checkout -b SomeBody-improvement master
    git pull git://github.com/SomeBody/fish-shell.git improvement
    git rebase master
    git checkout master
    git merge SomeBody-improvement
    git pull --rebase ; git push
    
  2. If the branch or pull request contains a lot of important history you should do a regular merge. For example, a large feature was developed incrementally, and most revisions are testable. Then it can be useful to preserve true history, so we can track down exactly when a regression occurred (e.g. with git bisect). In that case, do a regular merge. The steps are the same as for a rebase, except omit the git rebase master line.

  3. If the branch or pull request contains a lot of unimportant history - "thrashing around" - then do a squash merge:

    git checkout -b SomeBody-improvement master
    git pull git://github.com/SomeBody/fish-shell.git improvement
    git checkout master
    git merge --squash SomeBody-improvement
    [Add a commit message explaining what you did]
    git pull --rebase ; git push
    
  4. Alternatively, git rebase --interactive can also squash commits, but will keep attribution

    git checkout -b SomeBody-improvement master
    git pull git://github.com/SomeBody/fish-shell.git improvement
    git rebase --interactive master
    [Edit according to the instructions]
    git checkout master
    git merge SomeBody-improvement
    [This should now be a fast-forward which does not create a merge-commit]
    git pull --rebase ; git push