Tentative git workflow suggestions
Closed, ResolvedPublic

Description

NOTE: This page is a work-in-progress

Commit Messages

Here is a nice article on writing commit messages in general: https://chris.beams.io/posts/git-commit/
The article highlighted seven points, listed as follows:

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how

While these rules are not in any way enforced by git, I suggest everyone to try to follow them whenever possible. The article contains some good explanations on the reasoning behind these rules.

Some editors (e.g. vim) has built-in formatting tools and highlighting to help with formatting the commit messages.

Do not do git commit -m "<commit message>" as this will certainly not format the commit message properly. Don't use the -m parameter. Instead, let Git open up the commit message editor. (You can change the editor choice.)

KDE-specific Commit Keywords

The KDE git server contains commit hooks to perform actions when certain keywords are detected in the commit message. They are listed on this two pages: https://community.kde.org/Infrastructure/Git/Hooks#Keywords, https://community.kde.org/Policies/Commit_Policy#Special_keywords_in_GIT_and_SVN_log_messages

The most-used keywords are:

  • BUG: <bug number> and CCBUG: <bug number>, where <bug number> is the bug number on the KDE Bugzilla. Having either of these keywords will post a comment on the referenced bug, linking the bug to the commit. In addition, the BUG keyword will close the referenced bug as FIXED, while CCBUG does not.
  • CCMAIL: <email address> will send a mail about the commit to the listed <email address>. It is often used as CCMAIL: kimageshop@kde.org to notify the mailing list on huge changes.
  • Differential Revision: https://phabricator.kde.org/DXXXX, where DXXXX is the Differential revision number. Having this keyword with the right URL will: (1) close the referenced revision and (2) update the revision diff to the actual changes in the commit.
  • While not a keyword, I advocate using Maniphest Tasks: TXXXX, where TXXX is the Mahiphest task number, to help linking between the relevant Maniphest task and the commit. This is the keyword added by the Arcanist tool when it creates a commit.

These keywords should be placed at the end of the commit message, separated from the main commit message with an empty line. Each keyword has to be placed at the start of a new line.

Fetching Updates from Remote

Never perform a plain git pull (unless you set the git config pull.ff = only on git 2.x). If you have pending local commits on the current branch, doing a plain git pull will automatically create a merge commit, which adds clutter to the commit history. Instead, consider using one of the following commands depending on the situation:

  • git pull --ff-only: This command fetches the updates from the remote, then applies them to the local branch only if they can be fast-forwarded, i.e. you don't have pending local commits on the branch. This is for when you just want to fetch updates and apply them if possible. (Note: this is the behaviour of git pull if the config pull.ff = only is set.)
  • git pull --rebase=preserve: This command fetches the updates from the remote, then performs a rebase while preserving merge commits. You really should only use this when you know what git rebase does. Specifying preserve is especially important if you have just merged a feature/topic branch, or otherwise your whole branch will be rewritten atop of the updated branch and you lose the merge commit. Because of this, I recommend git pull --rebase=preserve over git pull --rebase
  • git fetch origin --prune: This command fetches the updates and clean up references to deleted branches. The remote refs in the form of origin/<branch name> will be updated. After this, you can manually perform git merge --ff-only origin/<branch name> to achieve the same effect of git pull --ff-only, or git rebase --preserve-merges for the effects of git pull --rebase=preserve.

(The above assumes the remote is named origin, but if you somehow have a different remote name, you probably already know what you're doing.)

Branches

When to Use Branches

You can actually use a branch for everything, from temporary changes to small bugfixes to huge features. The important part is how to incorporate the changes back to the master branch (or other main branches). You can even ditch the branch if it's not useful. I tend to make commits directly on master only if I would immediately push the change afterwards.

Branch Naming

For branches that is to be pushed to the central KDE/Krita repository, branch names should be in the form of <your-kde-identity>/<topic-name>, or <your-kde-identity>/TXXXX-<topic-name> where TXXXX is the Maniphest task number. Branch names should be in lowercase (except for the T in the Maniphest task number and the D when referring to a Differential revision. Use hyphens (-) in place of spaces for the topic name, preferably not underscores. (If you feel that <your-kde-identity> is too long, ask Boud whether you can use something else.)

Bringing In the Changes by Rebasing

If the changes doesn't warrant a merge commit, it's better to not make it. You can rebase your branch atop of master and fast-forward master onto your branch. While being on your local branch, perform these commands:

  1. git fetch origin master to fetch the latest changes on the master branch
  2. git rebase origin/master to rebase your current branch atop of the remote master branch (you can add the flag -i to perform an interactive rebase to edit the commits if you want)
  3. Resolve conflicts if needed, and run git rebase --continue after fixing them
  4. git fetch . HEAD:master to move your local master branch to your current HEAD (the tip of your rebased branch)
  5. git checkout master

After that, verify that the rebase is done correctly by checking the git log and making sure it works. You can then push the changes.

Note: If your local master branch is already up-to-date and your commit(s) or local branch is directly on top of the latest commit on master, you can skip steps 1 to 3.

Note: Do not rebase a branch that has been shared on the central KDE/Krita repository, unless it is discussed and agreed upon.
Actually, if it is small enough I bet nobody would mind... but still, try to avoid doing this.

Merging a Feature/Topic Branch

Git merges by merging two parents (or more, but it's rarely done). The order of the parent is important -- avoid foxtrot merges: https://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/
You should always checkout master before performing the final merge of a feature/topic branch.
Note: it is fine to merge master into your branch periodically, but don't do it when you are about to merge the branch back into master.

A typical merge workflow would look like this:

  1. git fetch origin master:master to fetch the latest changes on the remote master branch and apply them to the local master branch
  2. git checkout master
  3. git merge --no-ff <branch-name>: Using --no-ff would make sure master won't fast-forward to a foxtrot merge... actually, if you already have a foxtrot merge in place, please redo the merge. (There is a command that would make a new commit by switching the two parents of your existing commit, but I don't know if it really works.)
  4. Resolve conflicts if needed.
  5. Add a descriptive message body to your merge commit introducing the feature/change, and add relevant keywords if needed. (Git should automatically show an editor for it, but if it doesn't because you're running an outdated version of Git, run git commit --amend to edit the message, and remember to add --edit to the git merge command next time.)

After making sure stuff still works, you can push the changes.

At the end, you should also delete your merged branch, both locally and remotely:

  1. git branch -d <branch-name>
  2. git push origin --delete <branch-name>

When to make Merge Commits?

I would say merge commits on the main branch (master) are good for whenever a bugfix or a new feature consists of more than a handful of related commits. Try not to abuse merging among feature/topic/private/temporary branches though.

If a branch you are merging consists of only one commit, you are probably doing it wrong.

alvinhochun updated the task description. (Show Details)
alvinhochun updated the task description. (Show Details)Feb 4 2018, 3:54 PM
alvinhochun updated the task description. (Show Details)Feb 5 2018, 3:19 PM
rempt added a subscriber: rempt.Feb 6 2018, 8:17 AM

The first-name actually should be your kde identity name, like mine is 'rempt', which is actually my surname.

alvinhochun updated the task description. (Show Details)Feb 6 2018, 12:12 PM
woltherav closed this task as Resolved.Apr 25 2019, 5:53 PM
woltherav claimed this task.
woltherav added subscribers: tymond, woltherav.

I think this has been resolved by @tymond's work