= Git branch tricks = At first Git might present a very different picture to a newbie, espcially if he/she has used other Source Code Management tools like Subversion or CVS. Most striking differnce is that there is no central repository for Git to operate. The repository is the .git directory created on a working tree. This presented considerable confusion to me when I tried to learn Git. Finally I stumbled across the idea and took time to digest. There are pages explains how to make git emulate the central repository model. I have never used it and now I am much more comfortable with Git's model than central repository model. Later when I started cloning (git-clone) and pulling (git-pull) from Linus' tree, I faced a very interesting problem. I created a branch by name experimental using the command, {{{ $ git-branch experimental }}} I make my own modifications to this branch. At the same time, linux kernel goes forward by adding many patches. So I needed to pull the latest branch. But I did not switch to master branch by doing {{{ $ git-checkout master }}} As a result, always my experiemental tree was merged, and not my master. So whenever I try to generate a patch by {{{ $ git-diff --patch-with-stat master experimental }}} I used to get all the differences applied to the main tree as well as the local patches I applied. So take care to do the git-checkout of the branch you wish to merge to. Sometimes you may find git doing a diff of a number of files using the command diff --git a/path/to/file b/patch/to/file The reason is that git thinks there is a difference between them because of the time stamp stored and the time stamp of the file is different. So either do {{{ $ git-status }}} or {{{ $ git-update-index --refresh }}} This would get rid of the diff --git .... messages. = Editing your git commits = Say you need to make a change to a patch you've submitted for review. There are several ways to do this. If the patch is your HEAD commit, you can run: {{{ git commit --amend -v}}} That will allow you to edit the commit message. If you add changes to the staging area with {{{`git add`}}}, you can add those changes to your commit with the above command, along with your previously committed changes. If you want to take the previous commit out of the git history, but leave the changes in your working tree, you can run: {{{ git reset --mixed HEAD^}}} If you want to completely get rid of all your changes, and revert all files to their state before your commit, you can use the {{{--hard}}} flag instead of the {{{--mixed}}} flag. Use this flag with care! = Editing a patch in a series = Should you need to edit a patch that's not the head commit (say patch 1 of 3), you can use the "interactive" mode of {{{git rebase}}}. Simply pass {{{git rebase}}} the {{{-i}}} flag, followed by the commit ID of the patch ''before'' the patch you want to edit. For example, say we had this git log: {{{ 40336d6 USB: xHCI: override bogus bulk wMaxPacketSize values eaadde4 xhci: fix list access before init 1f35618 xhci-mem: init list heads at the beginning of init c1be5a5 Linux 3.9}}} If I needed to edit commit 1f35618, I would run: {{{ git rebase -i 1f35618^}}} Git will then pop up a window with a list of commits: {{{ pick 1f35618 xhci-mem: init list heads at the beginning of init pick eaadde4 xhci: fix list access before init pick 40336d6 USB: xHCI: override bogus bulk wMaxPacketSize values # Rebase c1be5a5..40336d6 onto c1be5a5 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #}}} We want to edit commit 1f35618, so we change the word "pick" to "edit", and write and quit. Git will then rewind history to that commit, and you will be able to edit it with {{{`git add`}}} and {{{`git commit --amend -v`}}}. Once you've made your changes, you should run: {{{ git rebase --continue}}} You can always abort the rebase by running: {{{ git rebase --abort}}} Sometimes when you amend commits, you will run into conflicts. Git will place conflict markers ('<<<<' and '>>>>') in the effected files. You need to resolve those conflicts by editing the file, adding them with {{{`git add`}}} and then running {{{`git rebase --continue`}}}. Make sure to remove the "Conflicts" lines from your commits that git adds by default when there's a conflict.