Notes about using git.

Tips and tricks


Switch branches

$ git checkout <branch>

status

$ git status -sb

Show status in short format and also give branch info


show

$ git show

Shows log message and diff about the commit you are on.


log

$ git log -L 70,100:pkg/transformer/kubernetes/kubernetes.go

Get logs on file between line numbers.

$ git log --graph --abbrev-commit

Show graph in logs.


commit

$ git add -p

Commit only parts of file. Interactively choose chunks of patch.


blame

To see who wrote the code? For each line of the file what commit edited that line of code will be shown. So now you can use that git commit and pass it to git show <commit> to see all the changes.

$ git blame path/to/file

cherry-pick

To move a commit from one branch to another branch. Situation where: I committed to master when I meant to commit to my feature branch. I need to move my commit!

Get the commit hash

$ git show

Change to the branch you wanted to add that commit

$ git checkout <feature-branch>

Add it to the branch you are on

$ git cherry-pick <commit hash>

cherry-pick creates an entirely new commit based off the original, and it does not delete the original commit. So you will have to delete it manually. See below how to do it.

You can also get conflict during cherry-pick

$ git cherry-pick 435bedfa

Resolve the conflict and then

$ git cherry-pick --continue

reset

Remove the last commit.

$ git reset --hard HEAD^

HEAD : the commit I’m currently sitting on

HEAD^ : this commit’s parent

HEAD^^: this commit’s grandparent and so on

Remove the changes that were accidentally added and not comitted.

$ git reset HEAD

If you don’t want to have the uncommitted changes.

$ git reset --hard HEAD

rebase

  • rebase is a command for changing history.
  • Never change history when other people might be using your branch, unless they know you’re doing so.
  • Never change history on master.
  • Best practice: only change history for commits that have not yet been pushed.
$ git checkout master
$ git pull --ff upstream master
$ git checkout <feature-branch>
$ git rebase master -i

While pushing need to do force push because there is change of history. Local branch and remote branch have diverged.

$ git push origin <feature-branch> -f

In case of conflicts, find the conflicting file.

$ git status

reolve those conflicts and then continue the rebase

$ git status
$ git rebase --continue

Use the same commit message

Use the commit message that was generated automatically

git merge --no-edit

OR

git commit --amend --no-edit

Squashing commits

  • Amending the commit
$ git add missing-file
$ git commit --amend
  • Squashing

Look at last 5 commits. Below command will open the text editor.

$ git rebase --interactive HEAD~5

Once in editor, you can select which ones to squash into previous one and ones to pick as it is. Now type new commit message to squashed commits.


Splitting commits

$ git rebase --i HEAD~3

Now this will open the commit history in editor. The commit you want to split, change it from pick to edit. Save that file. Git will pause in the rebase process and give us time to create new commits. The too-big commit is already present, so let’s pop it off, but keep the changes:

$ git reset HEAD^

Not using --hard because we want to have the changes we wanted. Make changes as needed. Now add individual file and commit. And continue rebase.

$ git rebase --continue

Find no. of commits on your branch

If you have worked on a branch and have added bunch of commits to it, so how do you find out how many commits you have added?

$ git rev-list f28adfba5ec4f1b02153e9dcc0298ace118ca9d9..HEAD
5f3693549451429beb7ca17699d83a45f7d8ab49
a50cc4d9fe4d6feb3bb150f9762bad643adbacf0

This is two commits, you can pipe it to wc to find out the number.


bisect

The feature’s broken? But it was working fine 2 months ago… what changes? Bisect will help you find the commit that introduced the problem.

  • Need commit where it was working, commit where it’s broken and a test to verify that.
$ git bisect start
$ git checkout broken-commit
$ git bisect bad
$ git checkout working-commit
$ git bisect good

Auto-correct mis-types in commands

$ git config --global help.autocorrect 10

Edit git output colors

Set various colors to the git logs and all the git output

$ git config --global color.ui auto

Git merge from someone else’s fork

Add their github fork repo as a remote to a clone of your own repo:

$ git remote add other-guys-repo <url to other guys repo>

Get their changes:

$ git fetch other-guys-repo

Checkout the branch where you want to merge:

$ git checkout my_new_branch

Merge their changes in (assuming they did their work on the master branch):

$ git merge other-guys-repo/master

Resolve conflicts, commit the resolutions and voila. Quick Ref: http://stackoverflow.com/a/5606062


stash

Save the changes and clean the tree.

git stash

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.

git stash --include-untracked
git config --global alias.staash 'stash --include-untracked'

If the --include-untracked option is used, all untracked files are also stashed and then cleaned up with git clean, leaving the working directory in a very clean state.

git stash --all
git config --global alias.staaash 'stash --all'

If the --all option is used instead then the ignored files are stashed and cleaned in addition to the untracked files.


How to pull remote branch from somebody else’s PR

git remote add coworker git://path/to/coworkers/repo.git
git fetch coworker
git checkout --track coworker/foo

This will setup a local branch foo, tracking the remote branch coworker/foo. So when your coworker has made some changes, you can easily pull them:

git checkout foo
git pull

Quick Ref: http://stackoverflow.com/a/5884825

OR

Add following code snippet to ~/.bashrc, this will way you have alias to pull any PR.

function pr() {
    id=$1
    if [ -z $id ]; then
        echo "Need Pull request number as argument"
        return 1
    fi
    git fetch upstream pull/${id}/head:pr_${id}
    git checkout pr_${id}
}

Usage

pr <pr_number>

Tips on writing git commits


Tools

  • Commitizen - Helps in writing commits

  • Bash Git Prompt

    Install using following:

    cd && git clone https://github.com/magicmonty/bash-git-prompt.git .bash-git-prompt
    
    echo '
    #======================================
    # bash git prompt
    
    source ~/.bash-git-prompt/gitprompt.sh
    GIT_PROMPT_ONLY_IN_REPO=1
    #======================================
    ' | tee -a ~/.bashrc
    

Github

These are tips about using github.com

  • allow edits from maintainers

    This will help so that maintainers can push on your branch. On the PR at bottom right corner there is a check box to enable that.

  • Patch from PR

    If you want a patch/diff of changes in a PR just goto PR and at the end of the url put .patch and you will see formatted patch. e.g. goto PR and now the patch

  • Compare ranges

    goto https://github.com/<org>/<project>/compare/<old_version>...<new_version>

    OR

    goto https://github.com/kubernetes-incubator/kompose/compare/v0.3.0...v0.4.0

    Compare things like branches, releases, etc.

  • Compare, patch ranges

    goto https://github.com/<org>/<project>/compare/<branch>...<branch>.patch

    OR

    goto https://github.com/kubernetes-incubator/kompose/compare/v0.3.0...v0.4.0.patch

  • Anchors on line numbers

    Click on the line number and shift click on another line later to select a block of code.

  • References and closing issues/PRs

    Also you can add closes while merging the PR.

  • Code search

    repo:kubernetes-incubator/kompose is:pr registry in:title
    

    registry is the string I am searching in the kubernetes-incubator/kompose repo, which has that string in PR in title.

    OR

    repo:openshift/origin is:issue ubuntu
    

    When doing things on github you will find queries like these automatically generated.

  • Keyboard Shortcuts

    • ? for all the shortcuts.
    • Use t to search for files, fuzzy search, you need only file name not the full file path.

    Others can be found using ?.

  • Gists as full repos

    gists can act as full repos

  • Embedding the gist

    Add .pibb at the end of the gist link, you can use it on github pages and other places.

  • Short link to your github profile pic

    https://github.com/surajssd.png OR https://github.com/<github_username>.png

  • Short url with github

    Goto git.io and shorten any github url.

  • Blame

    On any file in github, you can click the blame button and see who made what changes. After clicking on some specific commit, you can see the complete change and from the commit message goto PR for seeing all the discussion.

  • Global list of issues, PRs

    In the top bar there are buttons for global list of issues and PRs. This can be a good todo list. In issues you can see issues you have created or assigned or mentioned.

  • Writing a very huge comment

    <details>
      write whatever here that needs to be hidden
    </details>
    

Ref: