logo

drewdevault.com

[mirror] blog and personal website of Drew DeVault git clone https://hacktivis.me/git/mirror/drewdevault.com.git

Using-git-with-discipline.md (6338B)


  1. ---
  2. date: 2019-02-25
  3. layout: post
  4. title: Tips for a disciplined git workflow
  5. tags: ["git", "philosophy"]
  6. ---
  7. Basic git usage involves typing a few stock commands to "[sync everyone
  8. up](https://xkcd.com/1597/)". Many people who are frustrated with git become so
  9. because they never progress beyond this surface-level understanding of how it
  10. works. However, mastering git is easily worth your time. How much of your day is
  11. spent using git? I would guess that there are many tools in your belt that you
  12. use half as often and have spent twice the time studying.
  13. [![](https://imgs.xkcd.com/comics/is_it_worth_the_time.png)](https://xkcd.com/1205/)
  14. If you'd like to learn more about git, I suggest starting with [Chapter
  15. 10][ch-10] of [Pro Git][pro-git] (it's free!), then reading chapters 2, 3,
  16. and 7. The rest is optional. In this article, we're going to discuss how you can
  17. apply the tools discussed in the book to a disciplined and productive git
  18. workflow.
  19. [ch-10]: https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain
  20. [pro-git]:https://git-scm.com/book/en/v2
  21. ### The basics: Writing good commit messages
  22. [![](https://imgs.xkcd.com/comics/git_commit.png)](https://xkcd.com/1296/)
  23. You may have heard this speech before, but bear with me. Generally, you should
  24. not use `git commit -m "Your message here"`. Start by configuring git to use
  25. your favorite editor: `git config --global core.editor vim`, then simply run
  26. `git commit` alone. Your editor will open and you can fill in the file with your
  27. commit message. The first line should be limited to 50 characters in length, and
  28. should complete this sentence: when applied, this commit will... "Fix text
  29. rendering in CJK languages". "Add support for protocol v3". "Refactor CRTC
  30. handling". Then, add a single empty line, and expand on this in the *extended
  31. commit description*, which should be hard-wrapped at 72 columns, and include
  32. details like rationale for the change, tradeoffs and limitations of the
  33. approach, etc.
  34. We use 72 characters because that's [the standard width of an email][rfc], and
  35. email is an important tool for git. The 50 character limit is used because the
  36. first line becomes the subject line of your email - and lots of text like
  37. "`[PATCH linux-usb v2 0/13]`" can get added to beginning. You might find
  38. wrapping your lines like this annoying and burdensome - but consider that when
  39. working with others, they may not be reading the commit log in the same context
  40. as you. I have a vertical monitor that I often read commit logs on, which is not
  41. going to cram as much text into one line as your 4K 16:9 display could.
  42. [rfc]: https://tools.ietf.org/html/rfc2822#section-2.1.1
  43. ### Each commit should be a self-contained change
  44. Every commit should only contain one change - avoid sneaking in little unrelated
  45. changes into the same commit[^1]. Additionally, avoid breaking one change into
  46. several commits, unless you can refactor the idea into discrete steps - each of
  47. which represents a complete change in its own right. If you have several changes
  48. in your working tree and only need to commit some of them, try `git add -i` or
  49. `git add -p`. Additionally, every commit should compile and run all tests
  50. successfully, and should avoid having any known bugs which will be fixed up in a
  51. future commit.
  52. [^1]: I could stand to take my own advice more often in this respect.
  53. If this is true of your repository, then you can check out any commit and expect
  54. the code to work correctly. This also becomes useful later, for example when
  55. cherry-picking commits into a release branch. Using this approach also allows
  56. [git-bisect](https://git-scm.com/docs/git-bisect) to become more useful[^2],
  57. because if you can expect the code to compile and complete tests successfully
  58. for every commit, you can pass `git-bisect` a script which programmatically
  59. tests a tree for the presence of a bug and avoid false positives. These
  60. self-contained commits with good commit messages can also make it really easy to
  61. prepare release notes with [git-shortlog][shortlog],
  62. [like Linus does with Linux releases][linux-announcement].
  63. [^2]: In a nutshell, git bisect is a tool which does a binary search between two commits in your history, checking out the commits in between one at a time to allow you to test for the presence of a bug. In this manner you can narrow down the commit which introduced a problem.
  64. [shortlog]: https://git-scm.com/docs/git-shortlog
  65. [linux-announcement]: https://lkml.org/lkml/2019/1/6/178
  66. ### Get it right on the first try
  67. We now come to one of the most important features of git which distinguishes it
  68. from its predecessors: history editing. All version control systems come with a
  69. time machine of some sort, but before git they were mostly read-only. However,
  70. git's time machine is different: you can change the past. In fact, you're
  71. encouraged to! But a word of warning: only change a future which has yet to be
  72. merged into a stable public branch.
  73. The advice in this article - bug-free, self-contained commits with a good commit
  74. message - is hard to get right on the first try. Editing your history, however,
  75. is easy and part of an effective git workflow. Familiarize yourself with
  76. [git-rebase](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) and use
  77. it liberally. You can use rebase to reorder, combine, delete, edit, and split
  78. commits. One workflow I find myself commonly using is to make some changes to a
  79. file, commit a "fixup" commit (`git commit -m fixup`), then use `git rebase -i`
  80. to squash it into an earlier commit.
  81. ### Other miscellaneous tips
  82. - Read the man pages! Pick a random git man page and read it now. Also, if you
  83. haven't read the top-level git man page (simply `man git`), do so.
  84. - At the bottom of each man page for a high-level git command is usually a list
  85. of low-level git commands that the high-level command relies on. If you want
  86. to learn more about how a high-level git command works, try reading these man
  87. pages, too.
  88. - Learn how to specify the commit you want with [rev selection][rev-select]
  89. - Branches are useful, but you should learn how to work without them as well to
  90. have a nice set of tools in your belt. Use tools like `git pull --rebase`,
  91. `git send-email -1 HEAD~2`, and `git push origin HEAD~2:master`.
  92. [rev-select]: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection