# Updated Kernel Hacker's guide to git

14 messages from 2006-12-21 to 2006-12-22. Participants: Jeff Garzik, Willy Tarreau, Nigel Cunningham, Jay Cliburn, Martin Langhoff, Junio C Hamano, Linus Torvalds, Francois Romieu, Guennadi Liakhovetski, Jesper Juhl.
Thread: https://gitlist.dev/t/6041

## Jeff Garzik, 2006-12-21 03:04

Subject: Updated Kernel Hacker's guide to git
Message-ID: <4589F9B1.2020405@garzik.org>
URL: https://gitlist.dev/e/4589F9B1.2020405%40garzik.org

```
I refreshed my git intro/cookbook for kernel hackers, at 
http://linux.yyz.us/git-howto.html

This describes most of the commands I use in day-to-day kernel hacking. 
  Let me know if there are glaring errors or missing key commands.

	Jeff

```

## Jay Cliburn, 2006-12-21 03:21

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <4589FD9E.2010000@bellsouth.net>
URL: https://gitlist.dev/e/4589FD9E.2010000%40bellsouth.net
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
Jeff Garzik wrote:
> I refreshed my git intro/cookbook for kernel hackers, at 
> http://linux.yyz.us/git-howto.html
> 
> This describes most of the commands I use in day-to-day kernel hacking. 
>  Let me know if there are glaring errors or missing key commands.

Thanks for doing this.  I've referred to your previous page rather often 
as I grope around trying to learn git and hack a vendor driver for 
submittal into the mainline kernel.

One thing that baffled me was how to use git to create a "kitchen sink" 
diff that would produce my entire driver suitable for submittal to lkml 
for review.  This probably isn't needed very often, but for new driver 
submittals it's important to know how to do it.  Francois Romieu showed 
me how (assume the new driver branch is named "driver"):

$ git diff $(git merge-base master driver)..driver

As a beginner, this command continues to be utterly non-intuitive to me, 
but it works.  There may be other ways to do it, too.

The point is, I think you should add instructions on your cookbook that 
address how to produce such a "kitchen sink" diff if you're submitting a 
brand new driver to lkml.  (Obviously I don't know what such a diff is 
actually called.)

Jay

```

## Willy Tarreau, 2006-12-21 05:44

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <20061221054445.GL24090@1wt.eu>
URL: https://gitlist.dev/e/20061221054445.GL24090%401wt.eu
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
Hi Jeff !

On Wed, Dec 20, 2006 at 10:04:17PM -0500, Jeff Garzik wrote:
> I refreshed my git intro/cookbook for kernel hackers, at 
> http://linux.yyz.us/git-howto.html

Thanks for this update, it was my most useful source of inspiration
when I started with git.

> This describes most of the commands I use in day-to-day kernel hacking. 
>  Let me know if there are glaring errors or missing key commands.

I very often use "git-format-patch -k -m" to produce individual patches
that I delay, merge in other branches, or even in other trees with
"git-am -k -3".  I believe it was Davem who suggested this a while ago,
and I agree it's very convenient to maintain a patch collection (and
sometimes to clean them up).

Also, I think that for beginners, you have not insisted enough on the
fact that they should not modify the master branch, but that they
should immediately create their own branch before any local changes.

I got caught by this when I started, and had trouble playing with the
origin branch to try to fix my mistakes.

Overall it's a good tutorial anyway.

Cheers,
Willy

```

## Nigel Cunningham, 2006-12-21 05:53

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <1166680407.3636.25.camel@nigel.suspend2.net>
URL: https://gitlist.dev/e/1166680407.3636.25.camel%40nigel.suspend2.net
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
Hi.

On Wed, 2006-12-20 at 22:04 -0500, Jeff Garzik wrote:
> I refreshed my git intro/cookbook for kernel hackers, at 
> http://linux.yyz.us/git-howto.html
> 
> This describes most of the commands I use in day-to-day kernel hacking. 
>   Let me know if there are glaring errors or missing key commands.

Thanks for the work! I'd suggest also saying how to repack and cleanup.
Could also be a good idea to go through the steps for uploading to
master.kernel.org or elsewhere?

Regards,

Nigel

```

## Martin Langhoff, 2006-12-21 07:04

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <46a038f90612202304uabdffacld857cfcb90ec3e76@mail.gmail.com>
URL: https://gitlist.dev/e/46a038f90612202304uabdffacld857cfcb90ec3e76%40mail.gmail.com
In-Reply-To: <4589FD9E.2010000@bellsouth.net>

```
On 12/21/06, Jay Cliburn <jacliburn@bellsouth.net> wrote:
> $ git diff $(git merge-base master driver)..driver

There is a nicer way to do it with 1.4.x git -- note the 3 dots:

$ git diff master...driver

cheers,


martin

```

## Junio C Hamano, 2006-12-21 07:32

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <7vk60l1z7u.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vk60l1z7u.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <46a038f90612202304uabdffacld857cfcb90ec3e76@mail.gmail.com>

```
"Martin Langhoff" <martin.langhoff@gmail.com> writes:

> On 12/21/06, Jay Cliburn <jacliburn@bellsouth.net> wrote:
>> $ git diff $(git merge-base master driver)..driver
>
> There is a nicer way to do it with 1.4.x git -- note the 3 dots:
>
> $ git diff master...driver

Careful.

I think Jay was looking at this kind of ancestry graph:

         *---*---*---* driver
        /
 --o---o---x---x---x---x master

There might be quite a few merges on either side, but the point
is '*' are not yet 'in', and 'o' and 'x' are already in the
'upstream (but 'x' are not in Jay's driver yet).

The three dots would give both '*' and 'x'; I do not think that
is what Jay wants.  A submitter to mainline usually wants only
'*' commits.

I've always thought that 'submission' is supposed to be done as
a series of patches, in which case a reasonable way would be to
do:

	git format-patch -n master driver

If on the other hand a single roll-up patch is desired, I think
the most reasonable thing to do is to first merge the tip of the
master to the tip of driver, resolve all the conflicts as
needed, and take the diff between the 'master' and the result:


         *---*---*---*---y driver (y is the test merge)
        /               / 
 --o---o---x---x---x---x master

	git checkout driver
        git merge master
	... resolve conflicts if any, then "git commit"
	git diff master

This diff by definition should apply cleanly to the tip of
'master' and would result in the source that contains the
updates for the driver.

When you are done, it would be advisable to do:

	git reset --hard HEAD^

to remove that 'y' merge, unless the merge involved a true
conflict resolution.

```

## Linus Torvalds, 2006-12-21 07:51

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <Pine.LNX.4.64.0612202317110.3576@woody.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0612202317110.3576%40woody.osdl.org
In-Reply-To: <4589FD9E.2010000@bellsouth.net>

```


On Wed, 20 Dec 2006, Jay Cliburn wrote:
> 
> $ git diff $(git merge-base master driver)..driver

Be careful. This ONLY works if you don't have criss-cross merges etc, so 
you need to be somewhat careful about it. If you end up having a complex 
merge history between the origin branch and your development tree, things 
will stop working

So it's actually worth understanding what the above does.

Here's the picture to keep in mind: you started off with something like 
this:

	<- older			newer ->

	..--A---B---C---D

where the top commit was D, and you started doing your own work off there. 
However, the tree you are tracking (doing "git fetch origin" or somethng) 
ALSO continues, so soon enough you'll have a history that looks like

	<- older			newer ->

	..--A---B---C---D---E---F---G---H <-"origin"
	                 \
	                  --X---Y---Z <- your "driver" branch"

where your work is the "X-Y-Z" sequence.

How, the reason you must NOT do

	git diff origin..driver

or something like that, is that it will LITERALLY do a diff between those 
two heads. And while that is a perfectly normal diff, it's not what you 
want: it's the diff between the up-stream work and yours, and it will show 
that a lot of work has _not_ happened in your branch (all the E-F-G-H 
stuff), and then you've added some work (X-Y-Z).

What you obviously WANT to have is the "diff" between "D" (which was the 
point where you started) and "Z" (which is where you are now. That's what 
you want to send up-stream.

Now, the way people used to do this under CVS, was to simply _remember_ D. 
Preferably by doing a tag at the point where they started working. Then 
you can always diff against that tag.

You can do that in git too, of course, but it would just be stupid. 
Because git actually _knows_ the history, so you can just ask git

	"What is the most recent commit that both 'origin' and 'driver'
	 have in common?"

the answer, of course, is the very commit you want: D. And how do you ask 
for that "most recent common commit"? That's right: it's called the "merge 
base", because it's also the thing you'd use as the base in a bog-standard 
three-way merge.

So "git merge-base origin driver" just returns "D", without you having had 
to tag it or remember it at all.

So when you do

	git diff $(git merge-base origin driver)..driver

you're literally asking for the diff between your current top of the 
"driver" branch, and the place where you diverged from "origin".

Now, why do I mention the fact that THIS DOES NOT WORK if you do merges 
and you no longer have a linear tree? Think about it. If you actually ever 
pull on the up-stream and create a merge in your development tree, the 
commit history graph will now look something like this:

	<- older			newer ->

	..--A---B---C---D---E---F---G---H <-"origin"
	                 \        \
	                  --X---Y--M--Z <- your "driver" branch"

where the "M" commit is because you merged some new work from origin.

But see what that did to the most recent commit? Now, the most recent 
commit is no longer "D". In fact, it's not even your "merge" commit, if 
you think about it (even though you might naively think so), because that 
merge commit doesn't even exist in "origin", so clearly it cannot be the 
most recent common commit.

The most recent commit in common is "F". So now,

	git diff $(git merge-base origin driver)..driver

will give the difference between _F_ and your current tip Z.

The thing is, THIS IS STILL THE RIGHT THING TO DO. It's magic. Since you 
did a merge in M, all the things up until F have been merged into Z too, 
so you actually NO LONGER want to diff against D. Nor do you want to diff 
against M (since that would mean that you would not see the work you did 
in X and Y). 

By doing a diff against F (and your own merge having done the right 
thing), you actually end up getting the "union" of work for X-Y-Z when you 
do that magic command line.  If you had done it against D, you'd have seen 
the work in E and F that the merge M brought in - but you don't want that, 
because you want just the work YOU did, not anything in "origin".

So what you want is actually exactly again the most recent common commit.

HOWEVER. While it magically "just works" in things like this, it doesn't 
actually work for the really complex cases. If I've merged an eariler 
version of your work AND you did a merge from me too, you can have a 
criss-cross merge where there simply isn't one "most recent common commit" 
at all any more, but two or more. And then you really do need to do more.

This is one reason why I suggest developers not merge from me very often: 
if your development tree is just a straight line (ie you only had that one 
merge), you can't ever even get in that situation, and perhaps as 
importantly, if/when I pull from you, the result will also tend to look 
more understandable to people who look at the history.

But another way to avoid a criss-cross merge is actually to never let me 
see your tree at all, and then you can merge with me as often as you damn 
well like. And in that case, the magic

	git diff $(git merge-base origin driver)..driver

is always going to give you exactly what you want. You can use merges to 
keep up-to-date, and always see what you want to send off by email 
upstream. The history will look like crap (you'll end up having a ton of 
merges in your tree), but if you aren't going to publicise your history 
anyway (just the diff end result), why would you care?

(And yes, you can actually do "git diff origin...driver" with _three_ 
dots. I'm not even going to explain _why_ that works, because that's a 
whole other kettle of fish, and is actually a magic special case in 
builtin-diff.c. So feel free to use it because it's short and sweet, but 
the long format is actually easier to explain what it actually MEANS).

		Linus

```

## Jeff Garzik, 2006-12-21 11:44

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <458A73A6.4010805@garzik.org>
URL: https://gitlist.dev/e/458A73A6.4010805%40garzik.org
In-Reply-To: <1166680407.3636.25.camel@nigel.suspend2.net>

```
Nigel Cunningham wrote:
> Hi.
> 
> On Wed, 2006-12-20 at 22:04 -0500, Jeff Garzik wrote:
>> I refreshed my git intro/cookbook for kernel hackers, at 
>> http://linux.yyz.us/git-howto.html
>>
>> This describes most of the commands I use in day-to-day kernel hacking. 
>>   Let me know if there are glaring errors or missing key commands.
> 
> Thanks for the work! I'd suggest also saying how to repack and cleanup.

Yes, I should mention repacking.  When you say cleanup, what 
specifically do you mean?


> Could also be a good idea to go through the steps for uploading to
> master.kernel.org or elsewhere?

Yes, push should be mentioned at the very least.

	Jeff

```

## Jeff Garzik, 2006-12-21 11:53

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <458A75B2.6050201@garzik.org>
URL: https://gitlist.dev/e/458A75B2.6050201%40garzik.org
In-Reply-To: <4589FD9E.2010000@bellsouth.net>

```
Jay Cliburn wrote:
> Jeff Garzik wrote:
>> I refreshed my git intro/cookbook for kernel hackers, at 
>> http://linux.yyz.us/git-howto.html
>>
>> This describes most of the commands I use in day-to-day kernel 
>> hacking.  Let me know if there are glaring errors or missing key 
>> commands.
> 
> Thanks for doing this.  I've referred to your previous page rather often 
> as I grope around trying to learn git and hack a vendor driver for 
> submittal into the mainline kernel.
> 
> One thing that baffled me was how to use git to create a "kitchen sink" 
> diff that would produce my entire driver suitable for submittal to lkml 
> for review.  This probably isn't needed very often, but for new driver 
> submittals it's important to know how to do it.  Francois Romieu showed 
> me how (assume the new driver branch is named "driver"):
> 
> $ git diff $(git merge-base master driver)..driver
> 
> As a beginner, this command continues to be utterly non-intuitive to me, 
> but it works.  There may be other ways to do it, too.
> 
> The point is, I think you should add instructions on your cookbook that 
> address how to produce such a "kitchen sink" diff if you're submitting a 
> brand new driver to lkml.  (Obviously I don't know what such a diff is 
> actually called.)

You inflict upon yourself all sorts of pain if you keep updating 
'master', but don't merge that into 'driver'.  Typically you want to 
rebase after updating master:

	git checkout driver
	git rebase master
	# build and test
	git prune

or merge master into your current branch:

	git checkout driver
	git pull . master
	# build and test

That way, you are GUARANTEED that

	git diff master..driver

will result in a diff that you can send upstream.

One moral of this story, as (I think) Linus mentioned, don't update 
'master' too frequently.  That's one key lesson of distributed 
programming.  Unless the upstream kernel has a key API change or bug fix 
you need, just pretend the outside world does not exist, and hack away 
on your driver.

	Jeff

```

## Francois Romieu, 2006-12-21 13:53

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <20061221135349.GB25184@electric-eye.fr.zoreil.com>
URL: https://gitlist.dev/e/20061221135349.GB25184%40electric-eye.fr.zoreil.com
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
Jeff Garzik <jeff@garzik.org> :
> I refreshed my git intro/cookbook for kernel hackers, at 
> http://linux.yyz.us/git-howto.html
> 
> This describes most of the commands I use in day-to-day kernel hacking. 
>  Let me know if there are glaring errors or missing key commands.

o 'git whatchanged shnortz' can probably be replaced with
  'git log -- schnortz' so there is one command less to remember.

o "Display changes since last git-update-index:"
  Fine but you have not told the reader what git-update-index is.

-- 
Ueimor

```

## Guennadi Liakhovetski, 2006-12-21 20:40

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <Pine.LNX.4.60.0612212135230.5551@poirot.grange>
URL: https://gitlist.dev/e/Pine.LNX.4.60.0612212135230.5551%40poirot.grange
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
On Wed, 20 Dec 2006, Jeff Garzik wrote:

> I refreshed my git intro/cookbook for kernel hackers, at
> http://linux.yyz.us/git-howto.html

Very nice, thanks! A couple of remarks from an absolute git newbie:

1. I heard "git am" is supposed to supersede apply-mbox

2. What I often have problems with is - what to do if git spits at me a 
bunch of conflict messages after a seemingly safe pull or similar. Don't 
know if you want to cover those points but "git troubleshooting" would 
definitely be a valuable document.

Thanks
Guennadi
---
Guennadi Liakhovetski

```

## Jeff Garzik, 2006-12-21 20:46

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <458AF2AC.4080304@garzik.org>
URL: https://gitlist.dev/e/458AF2AC.4080304%40garzik.org
In-Reply-To: <Pine.LNX.4.60.0612212135230.5551@poirot.grange>

```
Guennadi Liakhovetski wrote:
> On Wed, 20 Dec 2006, Jeff Garzik wrote:
> 
>> I refreshed my git intro/cookbook for kernel hackers, at
>> http://linux.yyz.us/git-howto.html
> 
> Very nice, thanks! A couple of remarks from an absolute git newbie:
> 
> 1. I heard "git am" is supposed to supersede apply-mbox

Hey, that's pretty neat.  Glad you told me, this should improve my 
workflow a bit.


> 2. What I often have problems with is - what to do if git spits at me a 
> bunch of conflict messages after a seemingly safe pull or similar. Don't 
> know if you want to cover those points but "git troubleshooting" would 
> definitely be a valuable document.

Agreed.

	Jeff

```

## Nigel Cunningham, 2006-12-21 21:17

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <1166735878.5906.3.camel@nigel.suspend2.net>
URL: https://gitlist.dev/e/1166735878.5906.3.camel%40nigel.suspend2.net
In-Reply-To: <458A73A6.4010805@garzik.org>

```
Hi.

On Thu, 2006-12-21 at 06:44 -0500, Jeff Garzik wrote:
> Nigel Cunningham wrote:
> > Hi.
> > 
> > On Wed, 2006-12-20 at 22:04 -0500, Jeff Garzik wrote:
> >> I refreshed my git intro/cookbook for kernel hackers, at 
> >> http://linux.yyz.us/git-howto.html
> >>
> >> This describes most of the commands I use in day-to-day kernel hacking. 
> >>   Let me know if there are glaring errors or missing key commands.
> > 
> > Thanks for the work! I'd suggest also saying how to repack and cleanup.
> 
> Yes, I should mention repacking.  When you say cleanup, what 
> specifically do you mean?

Oh, I was just thinking of the related commands - prune-packed,
count-objects, fsck-objects and so on. (I know repack does prune-packed
when you use -d, but it might be handy to mention it anyway... or
not :>)

> > Could also be a good idea to go through the steps for uploading to
> > master.kernel.org or elsewhere?
> 
> Yes, push should be mentioned at the very least.

Nigel

```

## Jesper Juhl, 2006-12-22 08:50

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <9a8748490612220050t294d3785r94f0b3c74e935b24@mail.gmail.com>
URL: https://gitlist.dev/e/9a8748490612220050t294d3785r94f0b3c74e935b24%40mail.gmail.com
In-Reply-To: <4589F9B1.2020405@garzik.org>

```
On 21/12/06, Jeff Garzik <jeff@garzik.org> wrote:
> I refreshed my git intro/cookbook for kernel hackers, at
> http://linux.yyz.us/git-howto.html
>
> This describes most of the commands I use in day-to-day kernel hacking.
>   Let me know if there are glaring errors or missing key commands.
>
Very nice.

A bit on how to revert a commit and how to rebase a branch would make
it even nicer :)

Thank you for a very good document, Jeff.

-- 
Jesper Juhl <jesper.juhl@gmail.com>
Don't top-post  http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please      http://www.expita.com/nomime.html

```
