Douglas Muth on 10 Dec 2010 09:59:03 -0800


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] new to git - have questions


On Fri, Dec 10, 2010 at 12:04 PM, Eric at Lucii.org <eric@lucii.org> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> New git user here.
>
> Project is in git (yay!)
>
> Two programmers are now going to work on it and I don't have a good idea of the
> work flow.
>
[snip]

You're thinking about it wrong. :-)

Just to make sure we're on the same page here, unlike CVS where you
"checkout" code, in Git you actually "clone an entire repository".
That's a central part of Git.  One of the implications of this is that
any checkins that are made happen against the local repository.
Nobody else sees those changes until you do a "push" to another
repository.

Also note that I did not say "master repository". Since each
repository is a complete repository in its own right, Git is actually
a peer to peer system.  You can have two programmers, each with their
own repositories, pushing and pulling from each other's repository if
they wanted to. (though in practice, it's usually easier to have a
repository hanging out in /var/git/repository-name.git or similar.
People will have an easier time understanding the concept of "push
your changes to a common location".).

To further explain this, I'll draw a little ASCII art.  Let's say the
central repository has these commits:

A -- B

In this case, B is HEAD.

Let's say each programmer clones the repository and commits a change.
You'll have this:

Central: A -- B
Programmer 1: A -- B -- C
Programmer 2: A -- B -- C'

Now programmer 1 does a push to the central server (also known as
"origin" by default in Git's list of remote repositories):

Central: A -- B -- C
Programmer 1: A -- B -- C
Programmer 2: A -- B -- C'

What just happened to central was known as a "fast forward" in Git.
When doing the push, Git saw that the HEAD on Central (B) was in
Programmer 1's revision history, so it simply added the changes after
it.  That's also important: while CVS and SVN are version-oriented,
Git is change-oriented.

Now programmer 2 can try to do a push, but he'll get an error, since
the new HEAD (C) isn't in his history.  First, he'll have to do a
pull, resulting in:

Central: A -- B -- C
Programmer 1: A -- B -- C
Programmer 2: A -- B -- C -- C'

The way that happened is that Git worked its way backward through the
linked list of changes in Programmer 2's repository until it found a
common commit (B), replayed all of the changes from Central onto that
(C), then replayed all of the local changes (C') onto that.  C' is
still the HEAD for programmer 2.

This sounds complicated, and it is, but it works pretty well in
practice.  Conflicts are rare.  Nuclear escalations are even rarer.

Finally, Programmer 2 does his push, and a fast-forward on Central
happens again, resulting in this:

Central: A -- B -- C -- C'
Programmer 1: A -- B -- C
Programmer 2: A -- B -- C -- C'

As a sidenote, if you wondered about how nodes in these linked lists
were being shuffled around and if there were nodes being orphaned, yes
there were. :-)  That's one reason why Git periodically does garbage
collection.

Hope this helps,

-- Doug

-- 
Douglas T. Muth * Philadelphia, PA, USA
http://www.dmuth.org/
http://twitter.com/dmuth
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug