Skip to content
This repository has been archived by the owner on Aug 1, 2019. It is now read-only.

Git Cookbook

Bruno Besson edited this page Dec 20, 2017 · 5 revisions

Creating a new branch

When working on a new feature or a fix, it is recommended to create a dedicated branch instead of working in one's copy of the master branch.

Make sure the master branch is up-to-date:

git pull

Create a new branch and switch to it:

git checkout -b <branch name>

After changes have been done, added/committed to the new branch:

git add <changed files>
git commit -m "<Description of the changes>"

push the branch back to github:

git push origin <branch name>

Switching to some other branch (eg. master):

git checkout master
git checkout <branch name>

Cancelling a change

To revert an uncommitted change on some file (change is lost!):

git checkout <file to revert>

To revert to some former version of a file:

git checkout <commit hash> <file to revert>

To temporarily cancel a change and restore it later, use git stash (see below).

Updating one's branch with commits pushed to branch master in the meantime

Load the branch to update:

git checkout mybranch

Make sure pending changes are committed:

git status
git add ...
git commit -m "message describing the change"

or stash (hide) them temporarly:

git stash

To reapply stashed changes:

git stash pop

Get up-to-date branches from the remote repository (origin) in the local repository (saved as origin/<branch name> - for instance origin/master is the local copy of branch master from the origin repository):

git fetch

To fetch branches from another remote:

git fetch <remote repository name>

Rebase: move commits of the current branch on top of a the local (refreshed) copy of the branch master (ie. origin/master). New commits are placed at the end.

git rebase origin/master

Managing conflicts while rebasing

Figure out what files are conflicting:

git status

Edit files to fix conflicts and mark conflicts as solved by adding the edited files, then continue rebasing:

git add <edited files>
git rebase --continue

If it's really a mess: cancel:

git rebase --abort

All those instructions are documented when a problem is detected while rebasing.

Managing commits

It is possible to interactively reorder commits in the current branch as well as to remove them or merge some commits together.

First thing is to get the hash ("id") of the commit right before the list of commits to edit:

git log

Display the list of commits made after some commit and manipulate it in a text editor (-i = interactive):

git rebase -i <hash of the preceding commit>

In the text editor window it is then possible to reorder commits (by changing the commit lines order), removing some of them (remove the lines), or merge some together ("squash"). It is also possible to change commit messages. All actions are described in comments below the list of commits in the text editor window. fixup is quite handy: it merges the commit with the previous one, keeping only the previous commit message.

Be aware that reordering/removing/squashing commits may create conflicts.

When done with commits manipulation, save and close editor => rebase is then triggered. If no change was done in the commits list, the rebase does nothing.

When changes must be added to the very last commit, instead of rebasing it as above, it is possible to simply amend it:

git add <files to add the previous commit>
git commit --amend

Rebasing/amending causes the commits tree to be rewritten, thus being incompatible with the branch available on the remote repository. Doing a usual git push will then be reported as failing. It is required to force the push:

git push origin mybranch -f

Be aware that a forced push will replace the former version of the branch on the remote repository. It is irreversible except if someone else still has a copy of the old branch.

Testing a branch from a fork

(From https://davidwalsh.name/pull-down-pr/amp)

Pulling down requests from new contributors requires some work in order to navigate to their fork, etc.

There is an alias for easily pulling down requests:

git config --global --add alias.pr '!f() { git fetch -fu ${2:-upstream} refs/pull/$1/head:pr/$1 && git checkout pr/$1; }; f'

git config --global --add alias.pr-clean '!git checkout master ; git for-each-ref refs/heads/pr/* --format="%(refname)" | while read ref ; do branch=${ref#refs/heads/} ; git branch -D $branch ; done' 

The first alias above, git pr, allows you to pull down a pull request by ID, creating an new branch for it:

$ git pr 4862
From https://github.com/devtools-html/debugger.html
* [new ref] refs/pull/4862/head -> pr/4862 Switched to branch 'pr/4862'

$

The second alias, git pr-clean, deletes all branches created with git pr:

$ git pr-clean
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 190 commits.
 (use "git push" to publish your local commits)
husky > npm run -s postcheckout (node v8.5.0)

Deleted branch pr/4862 (was 10fe5049).
$

Note: You must have a remote called `upstream` which points to the upstream repo.