Skip to content

Instantly share code, notes, and snippets.

@lassebenni
Created April 29, 2020 21:04
Show Gist options
  • Save lassebenni/37aec471b00914bdb5afd626af40ba3d to your computer and use it in GitHub Desktop.
Save lassebenni/37aec471b00914bdb5afd626af40ba3d to your computer and use it in GitHub Desktop.
GIT it?

"Saving" your files in Git is a bit different than in most programs or editors. In Git nomenclature, 'saving' your code or changes is referred to as committing code. This means that the changes are recorded as 'history' of the current working directory.

A commit is the Git equivalent of a "save". Traditional saving should be thought of as a file system operation. Saving changes ~ https://www.atlassian.com/git/tutorials/saving-changes

A commit applies to the entire directory, and all changes (i.e. removing a file, changing some code, renaming a folder) are 'added' simultaneously in one commit. These commits (saved changes) can be stacked on the developer's local repo before being 'pushed' out to the source repository. This makes it possible for the developer to keep working on a feature (or multiple) without internet connection, all the while keeping a clear working history of his/her changes. When the developer is ready to connect to the source/public repo, all these commits can be pushed in one go and added or merged to the source working history.

A "standard" Git workflow consists of the following: changing files, adding these changes, committing the changes and pushing the changes.

First: Lets create a new Git repository Heads-up : The λ symbol is my terminal's (CMDer) user-prefix symbol. Your's might be '$' or '>' depending on your terminal. The commands are typed after the symbol. When the symbol is omitted on a line, it means that the line is output by the CLI and not typed by me.

1 λ cd ~ git-repo 2 λ git init 3 Initialized empty Git repository in ~/git-repo Now we have an empty git repository to work with. It only has the bare bones files in the .git-folder and it's HEAD (pointer to current branch) points to refs/heads/master.

1 λ cat ~/git-repo/.git/HEAD 2 ref: refs/heads/master Status Using git status is essential in working with Git. It provides a summary of all the changes you have made and the files that are in a different state compared to the recent-most commit. This means that you can see what changes would be stored if you would execute git commit. It is important to regularly run a git status while you are working on your repo, and definitely always run a git status before running a commit! It does not however, show the working directory's commit history, which is shown by git log.

Let's see it in action. First change directory into the newly created git-repo folder and run the git status command.

1 λ cd git-repo 2 λ git status 3 On branch master 4 ​ 5 No commits yet 6 ​ 7 nothing to commit (create/copy files and use "git add" to track) This lists all the changes Git has seen since your previous commit. As there hasn't been a commit, and the folder is still empty, no commits are listed and the message 'nothing to commit' is displayed. Let's create an empty text file called firist.txt and see what happens!

1 λ touch first.txt Touch is the linux-based command to create a new file, on Windows you can enter the folder and use the right-mouse button to create the file.

Now when we run the ll command (or dir), we should have the .git folder and the first.txt file present in the git-repo folder.

1 λ ll 2 total 8 3 drwxr-xr-x 1 x009461 1049089 0 Apr 16 12:37 . 4 drwxr-xr-x 1 x009461 1049089 0 Apr 16 11:39 .. 5 drwxr-xr-x 1 x009461 1049089 0 Apr 16 11:39 .git 6 -rw-r--r-- 1 x009461 1049089 0 Apr 16 12:37 first.txt Running git status gives us the following:

1 λ git status
2 On branch master
3

4 No commits yet
5

6 Untracked files:
7 (use "git add ..." to include in what will be committed)
8

9 first.txt
10

11 nothing added to commit but untracked files present (use "git add" to track) This tells us we are working on the 'master' branch, we have no commit history for the working directory and that there are untracked files inside the directory: first.txt. Git suggests we run the command git add to start tracking the currently untracked files. What does that exactly mean? This brings us to the point of tracking in Git.

Tracking

After running git init, whether run in an empty folder or existing project folder, all current and future files and folders within a the local repository will be watched by git. Git categorizes files and folders into three types:

Tracked ~ Here a file has been staged (ready for committing) or committed. Untracked ~ File has not been staged or committed Ignored ~ File is explicitly being ignored (specified in the file .gitignore) Currently our first.txt is untracked: the default state for newly created files. Since we only just created the file, and have not specified to Git whether we want to track it for the next commit, Git lists it as such. Let's get this baby tracked so we can commit it to our working directory history.

Add The git add command adds files to the staging area. It basically tells Git that you want the changes to be tracked and included in your next commit so they will persist in the working directory's history. This staging area is the place where all changes are tracked, ready to be committed. It's possbile to do a bunch of changes to your working directory but only add some of the files/changes to the staging area, commit those changes while leaving the other changes out. Later on you could add the other changes to staging and commit those as well (in a single, or separate commits). This way commits can be used with surgical precision, only containing those specific changes the developer wants to add to the commit history.

It's even possible to only add certain parts of a changed file to staging. Maybe you only want to add one function in a specific script to the next commit, even though you changed many parts in the script-file.

Let's try adding our first.txt to staging by using git add [name-of-file].

1 λ git add first.txt 2 λ git status 3 On branch master 4 ​ 5 No commits yet 6 ​ 7 Changes to be committed: 8 (use "git rm --cached ..." to unstage) 9 ​ 10 new file: first.txt We added the first.txt and ran git status, which shows that the file has been added to the changes to be committed: area a.k.a staging. Now if we would run git commit we would create a commit where the single action was the adding of the empty first.txt file to the repo.

Adding all to staging. Above, we specified the name of the file we wanted to add git add first.txt. This is valid and can be done for all the suggested changed when running git status. However, you can run git add . (git add dot) to automatically add all the modified files in the current dir to staging, instead of manually adding them. Another way is to use git add -A or git add --all which does the same, but for the entire repository.

There are a bunch of paramaters/options for add (which you can list by using git add -h), like -n for dry-running (testing without actually moving to staging) and -f for forcing ignored files to be added. Interactive mode is another interesting one, where certain parts/lines of a file can be staged while others are not. It is started by adding -i or --interactive to the git command. Since this is a more advanced topic, we will not divulge in it here. For now, let's finally see what all that committing talk is about!

Committing Since we created a file and added it to the staging area, and are pleased with our work so far, we can commit this to our history. Run the following command to do exactly that: git commit. This should take you to 'editor' mode in the terminal, or perhaps it will open a text editor for you. This is normal procedure, since we are required to add a commit message to the commit. This commit message is the bread-and-butter of our commits, it should specify what the commit is all about and what changes/actions it brings forth. Some adhere to particular messaging styles like using present-tense, imperative-style for a commit message (Add file first.txt) as if giving out orders to your codebase. A lot has been written about best-practices or conventions for commit messages.Git doesn't require commit messages to follow any specific formatting constraints, but the canonical format is to summarize the entire commit on the first line in less than 50 characters, leave a blank line, then a detailed explanation of what’s been changed.

Whatever conventions you use, they should be consistently implemented by you and your team members. Anyway, for now just enter a message, usually the first commit is called "Initial commit" to differentiate it from the subsequent ones. Whatever you choose, the commit message cannot be empty nor can it consists out of a single commented line (starting with #).

1 Initial commit 2

Please enter the commit message for your changes. Lines starting

3

with '#' will be ignored, and an empty message aborts the commit.

4

5

On branch master

6

7

Initial commit

8

9

Changes to be committed:

10

new file: first.tx

11

Saving this should result in the following output:

1 [master bae9550] Initial commit 2 1 file changed, 0 insertions(+), 0 deletions(-) 3 create mode 100644 first.txt Here master specifies the branch we are committing to, bae9550 is the hash-code generated to refer to this commit, followed by the commit message Initial commit. 1 file was changed, no insertions or deletions. Finally it displays some 'mode information' containing permissions and the file(s) modified. In this case our first.txt is a (100644): Regular non-executable file.

Commit message in-line. Instead of opening a text-editor to add the commit message, you can add it in-line with the -m [message-here] option. So git commit -m 'This is my message' is a shorter way of creating a commit.

Running git status shows us that there are no untracked files anymore:

1 λ git status 2 On branch master 3 nothing to commit, working tree clean And git log shows us our first and only commit:

1 commit 192f9461f8d1dad6c70fa05658a8443fc20a2f5a 2 Author: labenni lassebenninga@gmail.com 3 Date: Mon Apr 16 15:04:11 2018 +0200 4 ​ 5 Initial commit We have now succesfully 'saved' a change and created commit! Normally we should push it to a remote repo so it persists beyond our local machine and others could build on our work, although we would have to first configure some remote settings for that. For now, know that you have uncovered much of the regular Git workflow already!

The most basic features of GIT revolve around setting-up the local repository. These include INIT, CLONE and CONFIG.

Init Init creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository. The possible paramaters are --bare, --template, and --seperate-git-dir.

Bare initializes a git repo that lacks a working directory (codebase) and cannot be commited to by the developer. This is used for central repositories and servers as a singles-source-of-truth for the developers using the repo to push and pull their code to and from.

Template requires a predefined .git directory path. Custom/pre-defined git settings can be loaded into the new repo this way.

Clone Cloning copies the public repo and creating a local copy. This can either be the default branch (usually master), a specific branch, or a tag. By using the -depth=n parameter, a 'shallow-clone' is created where the depth of n refers to the amount n of most-recent commits to be copied. This can be useful when a repo with an extensive history is cloned, and the developer is only interested in the most-recent changes and codebase.

Bare vs Mirror Beside cloning a repo to start working on it (working directory), it is possible to use clone --bare and get a non-working directory containing history, branches and tags. This is a 'barebones' repository that can serve as a central repository to pull and push code from and to, but cannot be commited to and worked on. Mirroring a repo by using clone -mirror does the same as bare, but also copies all the external refs and links, so bascially makes a 1:1 copy of the original repository. This can be moved around to a new location or serve as a a back-up to the original.

Config Git can be customized by a number of options. The minimum of changes that most developers add are an email address and a name, to distinguish themselves when working on a repository. Other options to customize include the editor to configure git, the default merge-tool, a color-scheme and aliases for git commands, as well as formatting & whitespace.

Aliases

Creating aliases for git commands works mostly the same as on Linux-based systems. Often used commands can be shortened and chained with aliases. The following alias creates a shortcute 'ci' for the git command 'commit'.

1 git config --global alias.ci commit This can further be chained into a new command by referring to the just-created 'ci' alias. 1 git config --global alias.amend ci --amend As seen above, aliases can increase productivity (a lot) in the Git workflow. Whitespace & Formatting When 'diff-ing' changes in different files, differences in whitespace can be hard to see. The default Git configuration does the following things: Highlight orphan whitespaces at line endings. (blank-at-eol). Highlight space character that appears before a tab when indenting (space-before-tab). Highlighting of blank lines inserted at the end of a file (blank-at-eof). It is possible to disable these features. The following features are disabled by default and can be enabled by the developer:

http://localhost:8090/link/6#bkmrk-highlight-a-line-tha

Highlight a line that is indented with spaces instead of tabs (indent-with-non-tab). Highlighting an initial tab indent as an error (tab-in-indent). Highlighting a carriage-return at the line endings (cr-at-eol).

Sometime you want to start with a clean git history and remove any and all commits. As should be clear, this is only in a very special case where either the repo is a fork or you for some reason want to nuke your entire history.

When following these steps and removing the master branch in your project, pushing these changes to the source repo will probably make some other people very upset. Proceed with caution.

Checkout a new branch with the option --orphan. This creates a new unparented branch, not tied to the rest of the projects commit-history. 1 λ git checkout --orphan some_branch Since all files in the current branch are now untracked, remove and change files/folders as you fit for your first commit of the new history. When satisfied with the projects files/folders, run git commit -a -m "initial commit". This adds all the untracked files to be tracked and adds the message "initial commit". Of course, you can change the message to your pleasing, just remember that it will be the first message of your new commit history.

1 λ git commit -a -m "initial commit" Now we have our new commit history on the current branch, we can download the master branch that is tied to all the previous history. Use the capital -D flag to confirm the removal of the master branch. 1 λ git branch -D master Lastly, just rename the current branch to the master branch. Then run git log to confirm that we have indeed successfully re-written history! No trace of the previous commits exists. Unless you pull the origin's master branch and overwrite the current one again, that is. http://localhost:8090/link/9#bkmrk-%7Elasse

~Lasse

...continuing on from Commitment and other scary concepts.

Sometimes you want to see the changes you (or someone) else made in your working directory. Instead checking out specific commits and copying the source-code to your favorite editor for comparison, Git has you covered with diff.

To start, let's add some text to our first.txt:

1 λ echo "Some text" > first.txt Let's commit this immediately:

1 λ git commit -a -m "Add some text to first.txt" 2 [master d5630c6] Add some text to first.txt 3 1 file changed, 1 insertion(+) Git log should give us two different commits now:

1 λ git log 2 commit d5630c63d2e8ebb83b6ea7218c503838479f2742 (HEAD -> master) 3 Author: labenni lassebenninga@gmail.com 4 Date: Mon Apr 16 16:23:28 2018 +0200 5 ​ 6 Add some text to first.txt 7 ​ 8 commit 4a25ad083a5c65f61e97b5d2f470dbc7f048ba19 9 Author: labenni lassebenninga@gmail.com 10 Date: Mon Apr 16 16:00:59 2018 +0200 11 ​ 12 initial commit Now, lets' add some more text to our file by using echo (and double greater-than-signs, to append it to the file and not overwrite the contents):

1 λ echo "more text" >> first.txt 2 λ cat first.txt 3 "Some text" 4 "more text" Now, in our previous commit our first.txt file only container "Some text". After adding text to it, the file changed. Let's try to find this difference between the working directory and the previous commit. Run git diff.

1 λ git diff 2 diff --git a/first.txt b/first.txt 3 index fdc42a2..a83b6bd 100644 4 --- a/first.txt 5 +++ b/first.txt 6 @@ -1 +1,2 @@ 7 "Some text" 8 +"more text" The first line diff --git a/first.txt b/first.txt displays the differences in the working directory. Since we only have one change in one file, we get to see that: diff --git a/first.txt b/first.txt.

The second line index fdc42a2.. a83b6bd 100644 is metadata about the hash identifiers and file permissions. Usually this can be ignored completely.

The third and fourth line contain important 'change markers'. The --- stands for the changes from the previous version a, while the +++ symbols are associated with the most recent change b.

Below the change markers, the actual changes are displayed. Starting with the change header, which is enclosed with the @ symbol. This lists the line number of the changes and the amount of lines that are changed. In this case only one line is affected, the first one (-1) and 2 lines are added starting from line 1 (+1,2).

The remaining content of the diff chunk displays the recent changes. Each changed line is prepended with a + or - symbol indicating which version of the diff input the changes come from.

We can clearly see that "more text" was added to the existing line of "Some text".

Diffing branches. We just compared changes in a single file, without adding any arguments for a specific branch or commit to be compared. In our way, the default way, changes between the previous commit are shown. However, it's possible to compare the changes between specific commits and branches. For instance, this can be very useful when wondering what changed in a specific file or commit that introduced a bug.

To compare a specific branch, enter the branches you want to compare and seperate them with two dots to compare the tip (the most recent commit in the branch). Like so: git diff branch1..branch2. Notice the two dots between the names. Using two dots means you get all of the commits that branch2 has and branch1 does not have, so you can compare what you are missing in branch1. If you want to see commits that branch1 has that branch2 does not have and vice versa, you can use three dots: git diff branch1...branch2. In other words, if you are only interested in the changes in branch2, use two dots. If you are interested in the changes in both branch2 compared to branch1 and the changes in branch1 compared to branch2, use three dots.

     Image 1: Getting only the changes in B                                                             Image 2: Both changes in A and B

Diffing commits

Two compare commits, you should use the commit ID's (hash). The easiest way to look these up is by using git log. To search for a specific message you can append the --grep option.

1 λ git log --all --grep="initial" 2 commit 4a25ad083a5c65f61e97b5d2f470dbc7f048ba19 3 Author: labenni lassebenninga@gmail.com 4 Date: Mon Apr 16 16:00:59 2018 +0200 5 ​ 6 initial commit Comparing the current un-committed changes to those in the initial commit, just insert the commit ID: git diff 4a25ad083a5c65f61e97b5d2f470dbc7f048ba19.

1 λ git diff 4a25ad083a5c65f61e97b5d2f470dbc7f048ba19 2 diff --git a/first.txt b/first.txt 3 index e69de29..a83b6bd 100644 4 --- a/first.txt 5 +++ b/first.txt 6 @@ -0,0 +1,2 @@ 7 +"Some text" 8 +"more text" This shows that we added two lines of text since the initial commit when we added the empty first.txt file.

Diffing in git log

Instead of using git diff and inserting the commit ID's, it's possible to do this by using git log. Git log displays a overview of the all the commits in the current branch.

Comparing the latest two commits is as simple as doing a git log -p -2. This uses the -p command, which stands for patch (patch output differences) and the number of most recent commits, in this case 2.

1 λ git log -p -2 2 commit d5630c63d2e8ebb83b6ea7218c503838479f2742 (HEAD -> master) 3 Author: labenni lassebenninga@gmail.com 4 Date: Mon Apr 16 16:23:28 2018 +0200 5 ​ 6 Add some text to first.txt 7 ​ 8 diff --git a/first.txt b/first.txt 9 index e69de29..fdc42a2 100644 10 --- a/first.txt 11 +++ b/first.txt 12 @@ -0,0 +1 @@ 13 +"Some text" 14 ​ 15 commit 4a25ad083a5c65f61e97b5d2f470dbc7f048ba19 16 Author: labenni lassebenninga@gmail.com 17 Date: Mon Apr 16 16:00:59 2018 +0200 18 ​ 19 initial commit 20 ​ 21 diff --git a/first.txt b/first.txt 22 new file mode 100644 23 index 0000000..e69de29 Here we can see the overview that the two commits give us. The first commit, 4a25ad083a5c65f61e97b 5d2f470dbc7f048ba19, is compared to it's earlier state (which was just the bare git repository) and the change was the adding of a new file (first.txt).

The second commit, d5630c63d2e8ebb83b6ea7218c503838479f2742, adds a change to the first.txt file, adding the line "Some text". We can see the changes we made between the two commits. Easy, isn't it?

http://localhost:8090/link/8#bkmrk-we-should-note-that-

We should note that this overview above is overly simplified as there is only one file change. In a real project there might be tens or hundreds of changes and it can take some time to narrow down the specific one you are after, but this is to give a general overview of the workings of diff.

There is much ado about commit messages, committing-guidelines and the non-enforceable standards that follow them around. It seems that every community of developers has created their own view on what a commit should contain, how the message should be written and which open-source hero has the best commit history that we should all follow.

What most have in common however, is that they share the view that a very large amount of git messages as very confusing, bad or downright evil. These confusing, lazy git messages sometimes end up on codinghorror or blogs so others can laugh at the mess, so they serve some function, I guess. Anyway, the point of a commit message is to summarize the changes a specific commit applies to the codebase or problems it solves. A look at some guidelines while we are at it!

Github Commit Message Guidelines The popular Git hosting-website Github follows the following guidelines:

1 Short (72 chars or less) summary 2 ​ 3 More detailed explanatory text. Wrap it to 72 characters. The blank 4 line separating the summary from the body is critical (unless you omit 5 the body entirely). 6 ​ 7 Write your commit message in the imperative: "Fix bug" and not "Fixed 8 bug" or "Fixes bug." This convention matches up with commit messages 9 generated by commands like git merge and git revert. 10 ​ 11 Further paragraphs come after blank lines. 12 ​ 13

  • Bullet points are okay, too. 14
  • Typically a hyphen or asterisk is used for the bullet, followed by a 15 single space. Use a hanging indent. According to these rules, the following message would comply:

1 Switch libvirt get_cpu_info method over to use config APIs 2 ​ 3 The get_cpu_info method in the libvirt driver currently uses 4 XPath queries to extract information from the capabilities 5 XML document. Switch this over to use the new config class 6 LibvirtConfigCaps. Also provide a test case to validate 7 the data being returned. 8 ​ 9 DocImpact 10 Closes-Bug: #1003373 11 Implements: blueprint libvirt-xml-cpu-model 12 Change-Id: I4946a16d27f712ae2adf8441ce78e6c0bb0bb657 This also covers a lot of other practices in the Github convention, like external references and putting 'change-id' to the very end of the message.

Maybe it can help more to look at some bad examples:

1 commit 468e64d019f51d364afb30b0eed2ad09483e0b98 2 Author: [removed] 3 Date: Mon Jun 18 16:07:37 2012 -0400 4 ​ 5 Fix missing import in compute/utils.py 6 ​ 7 Fixes bug 1014829 What import? Why is it needed? What is bug 1014829? Probably a bug filed in some tracking-suite. The message accompanied with that bug would have been a better commit message:

1 Add missing import of 'exception' in compute/utils.py 2 ​ 3 nova/compute/utils.py makes a reference to exception.NotFound, 4 however exception has not been imported. Often the biggest mistakes is making the commit messages too vague or leaving out all the details and just referencing some other place where the full message is located.

A good commit message according to the Github convention adheres to these points:

It describes what the original problem is It describes the functional change being made It describes what the result of the change is It describes scope for future improvement A good commit message touches upon the following subjects in order: Problem -> Change -> Result -> Future.

Answer these questions for yourself before writing the message and try to fit the answers succinctly into your commit message. The masses that follow you into the code-swamps will thank you!

Angular committing guidelines The front-end amalgamation that is known as Angular (or is it AngularJS, or Angular5? Who knows) has it's own guidelines for commit messages. They even bundle the commit messages and use them to generate the Angular change log. Even more reason to have sharp rules about what kind of messages are allowed.

Here the message is broken down to three stages: the header, the body, and the footer. Angular developers are required to add the type, scope, and subject to the header.

1 (): 2 3

4 5 The type consists of the category of change within angular, for example a fix if it's a bug fix, a feat if the change is part of a feature. It must entail one of the types defined by the Angular team:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) docs: Documentation only changes feat: A new feature fix: A bug fix perf: A code change that improves performance refactor: A code change that neither fixes a bug nor adds a feature style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) test: Adding missing tests or correcting existing tests These types are general enough that they can be used across different projects. Maybe append the list with your own type if you really think it is necessary, but describe the newly added type carefully to prevent being superfluous.

The scope is optional, and refers to the name of the npm package affected by the commit (part of the angular-libraries). This is very Angular specific, some package names include animations, common, forms. For other projects, either create a scope of your own (maybe front-end, back-end, database) or omit the scope in your messages.

The subject is the summary of the change. The Angular team requires the following:

don't capitalize the first letter no dot (.) at the end use the imperative, present tense: "change" not "changed" nor "changes" An example would be:

fix(ivy): add unparsed selectors to the projectionDef instruction

Lastly the footer is used for reporting breaking changes if it contains any and, in that case, should then literally contain those words BREAKING CHANGE. If the commit closes some issue(s), this should be added to a separate line in the footer.

Adhering to these conventions can result in a consistent, readable commit history to keep your git blames as snappy as possible.

Chris Beams' seven rules of a great Git commit message Another set of rules I saw referenced multiple times, are Chris Beams' rules to a great commit message. Chris is a open-source developer that contributed heavily to Spring and Gradle. His seven rules are a collection of multiple standards and guidelines found on the internet.

Separate subject from body with a blank line Limit the subject line to 50 characters Capitalize the subject line Do not end the subject line with a period Use the imperative mood in the subject line Wrap the body at 72 characters Use the body to explain what and why vs. how Seperating subject from body with blank line helps when using tools like git log and git rebase, since they use the subject in their operations (like git log --oneline). The subject should limited to 50 characters, this adheres to GitHub's convention, and contain a summary of the change. Futhermore, it should be capitalized and not end with a period: punctuation is superfluous when you are saving space. The wording should be in an imperative mood (Fix the bug vs Fixed the bug). This is the way Git itself words it's messages. The following tip is handy when using the imperative wording. A correctly worded subject fits in the following sentence: "If applied, this commit will your subject line here". For instance: "If applied, this commit will clear low-level cache". This imperative mood is only necessary for the subject.

Now for the body. Wrap body at 72 characters per line so it is readable. Use the body to explain what and why v.s. how, meaning that other developers (and yourself) can read the commit message in the future and be sure what you did, and why. Chris puts it the following way:

In most cases, you can leave out details about how a change has been made. Code is generally self-explanatory in this regard (and if the code is so complex that it needs to be explained in prose, that’s what source comments are for). Just focus on making clear the reasons why you made the change in the first place—the way things worked before the change (and what was wrong with that), the way they work now, and why you decided to solve it the way you did.

~ Chris Beams

The body should contain the what and why, not necessarily the how.

Linus Torvalds Repository Rules So Linus Torvalds, father of Linux, has his own rules when you want to commit to one of his open-source projects. Basically I just copied the entire thing because by now I was getting a bit of exhausted with all these different ways of writing a message.

1 Also, please write good git commit messages. A good commit message 2 looks like this: 3 ​ 4 Header line: explain the commit in one line (use the imperative) 5 ​ 6 Body of commit message is a few lines of text, explaining things 7 in more detail, possibly giving some background about the issue 8 being fixed, etc etc. 9 ​ 10 The body of the commit message can be several paragraphs, and 11 please do proper word-wrap and keep columns shorter than about 12 74 characters or so. That way "git log" will show things 13 nicely even when it's indented. 14 ​ 15 Make sure you explain your solution and why you're doing what you're 16 doing, as opposed to describing what you're doing. Reviewers and your 17 future self can read the patch, but might not understand why a 18 particular solution was implemented. 19 ​ 20 Reported-by: whoever-reported-it 21 Signed-off-by: Your Name youremail@yourhost.com 22 ​ 23 where that header line really should be meaningful, and really should be 24 just one line. That header line is what is shown by tools like gitk and 25 shortlog, and should summarize the change in one readable line of text, 26 independently of the longer explanation. Please use verbs in the 27 imperative in the commit message, as in "Fix bug that...", "Add 28 file/feature ...", or "Make Subsurface..." Not much we had not seen before. Use a header line that contains the subject in a single line, use imperative wording, the body information should be wrapped in 74 chars (or so) per line, and should contain a description of your solution, possibly some background information, and the why. All of this more or less overlaps with the other methods we discussed above.

GIT-project messaging Guidelines The final one I want to discuss are Git's official(ish) guidelines for commits. They sum it to the following for contributing to the Git-project:

As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of “I added tests for” or “Adding tests for,” use “Add tests for."

~ Git SCM (18-4-2018)

So: a single line no more than about 50 chars, describing the changes concisely. Then a blank line, and a more detailed explanation that includes your motivation and contrast with previous behaviour. Furthermore, use the imperative present tense. Basically the first line can be seen as the subject in an email, and is used by git commands as a summary of the entire commit. It should be short and sweet, in the imperative. They refer to the guidelines by Tim Pope.

Conclusions http://localhost:8090/link/10#bkmrk-here-i-am-to-wrap-it

Here I am to wrap-it all up and give you the ultimate guidelines to commit messages! Well.. unfortunately I don't have the answer to that question, especially after reviewing all these guidelines. As much as it is a cop-out answer, I think you should adhere to the guidelines that you find most convenient for collaborating with your team. Obviously the large open-source projects have some rules that work for them, and could very well work for you, so another option is to just stick to one of the rules above. I think personally, I like the Angular guidelines for the typing of different commits. In the end, the point of the guidelines, I think, is to provide a consistent way of providing a story to your changes. Descriptions that are precise, include a sense of insight into the code, and maybe most importantly help you to find the changes that broke your build, will be beneficial to not only future-you, but all the poor saps that follow in your footsteps. God rest their souls. Happy gitting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment