GitWorkflows

From Git SCM Wiki
Jump to: navigation, search

This page attempts to decribe actual, useful, real-world things that people do with git, step by step.

How to revert your version of the kernel source back to the running version

If you actually run versions of the kernel on your machine that you've checked out of a git repository, you will see a uname that starts with a 'g' followed by a hex number:

# uname -r
2.6.18-g7e472020

That number is the beginning of the commit which marks the revision that you built your kernel. The next step is to find the full commit name:

dave@machine:~/linux-2.6.git$ git rev-parse 2.6.18-g7e472020
7e4720201ad44ace85a443f41d668a62a737e7d0

It is possible, since the kernel version doesn't contain a full commit that this isn't your revision, but it is highly unlikely.

Now that you've found the revision, you need to revert back to it:

$ git reset --hard 7e4720201ad44ace85a443f41d668a62a737e7d0

How to turn a git branch into a set of patches between revisions

First, get a git tree which was derived from another:

$ git-clone http://git.openvz.org/pub/linux-2.6.16-openvz linux-2.6.16-openvz

This could take a bit of time to download the whole thing. But, if you are wondering how to do this, you probably already have one of those.

Then you need to find a revision against which you would like to generate your patches. The easiest way to do this is to use an existing tag. Look at your tags directory:

linux-2.6.git$ ls .git/refs/tags/
2.6.16-git1   2.6.16-git2         v2.6.11       v2.6.13-rc3  v2.6.15      v2.6.16-rc3  v2.6.18
2.6.16-git10  2.6.16-git20        v2.6.11-tree  v2.6.13-rc4  v2.6.15-rc1  v2.6.16-rc4  v2.6.18-rc1
2.6.16-git11  2.6.16-git3         v2.6.12       v2.6.13-rc5  v2.6.15-rc2  v2.6.16-rc5  v2.6.18-rc2
...

The other way is to go find a revision manually. Run gitk, and then find the commit that you are interested in. In my case, this would be the one titled "Linux v2.6.18. Arrr!". I see "eead19bffcf064856ab8513afc395eaf80896e0f" in gitk's "SHA1 ID" field. This is the value you will need.

So, using either the tag name, or the SHA1 ID, run git-format-patch:

$ git-format-patch -o ../openvz-patches/ v2.6.18..
$ git-format-patch -o ../openvz-patches/ eead19bffcf064856ab8513afc395eaf80896e0f..
../openvz-patches/0001-Namespaces-support-from-mm-tree.txt
../openvz-patches/0002-Namespaces-support-from-mm-tree.txt
../openvz-patches/0003-Namespaces-support-from-mm-tree.txt
../openvz-patches/0004-Namespaces-support-from-mm-tree.txt

Note the ".." syntax after the revision you've specified. That is there to say "use that revision as a base, and go until the most recent revision". You could also put a revision after that, such as "v2.6.17..v2.6.18". That would give you all of the patches between 2.6.17 and 2.6.18. The same method also works with the raw SHA1 ID.

Voila! You should have a nice, linear set of patches.

How make sure your git tree doesn't have old, redundant cruft in it

$ git-pack-redundant --all | xargs --no-run-if-empty rm
$ git-prune-packed

How to edit a ChangeLog entry

My changelog for the top patch is wrong, what do I do?

$ git commit --amend

If you just need to add your SOB line:

$ git commit --amend -s

Note: don't ever do this on a publicly-available git tree.

How do I rearrange a set of commits

$ git rebase -i <commit-ish>

You would usually use "master" there for the <commit-ish>. You probably want to go find this with gitk.

You then get a nice file that looks like this:

pick 9feaa34 reduce kvm stack usage in kvm_arch_vm_ioctl()
pick a888f5b reduce stack usage in kvm_vcpu_ioctl()
pick e4a0c10 reduce stack usage in kvm_arch_vcpu_ioctl()
pick 8cd362a kvm: reduce stack usage in kvm_pv_mmu_op()

Rearrange this file as you like. If you want to edit a commit message for one of these, change the 'pick' to 'edit', and use the above command, with an additional -a:

$ git commit -a --amend

Note: don't ever do this on a publicly-available git tree.

How do I update a set of patches for a new tree from Linus (or anybody)

OK, so I've got a nice stack of patches on top of 'remotes/origin/master' and now I need to pull another copy from Linus and update on what I'm basing these patches.

       I get output like this:
$ git fetch
<should churn here a bit...>
From /home/dave/lse/linux/2.5/linux-2.6.git/
   c9272c4..f934fb1  master     -> origin/master
   c9272c4..f934fb1  origin     -> origin/origin
From /home/dave/lse/linux/2.5/linux-2.6.git/
 * [new tag]         v2.6.25    -> v2.6.25
 * [new tag]         v2.6.25-rc1 -> v2.6.25-rc1
 * [new tag]         v2.6.25-rc2 -> v2.6.25-rc2
...
$ git rebase FETCH_HEAD master
First, rewinding head to replay your work on top of it...
Applying reduce kvm stack usage in kvm_arch_vm_ioctl()
Applying reduce stack usage in kvm_vcpu_ioctl()
Applying reduce stack usage in kvm_arch_vcpu_ioctl()
Applying kvm: reduce stack usage in kvm_pv_mmu_op()

Here FETCH_HEAD is the new commit on which we are going to rebase, and master is the name of the branch which we are going to merge on top of FETCH_HEAD.

How to search for a deleted file

Courtesy of doener and hyperair on the git IRC channel.

This command gets a list of all filenames that ever existed in a project:

git log --all --pretty=format:  --name-only | sort -u

(Take note of the double spaces after `format:`)

You can then run this list through `| grep <pattern>` to search for old file names.


Personal tools