git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Subject: Re: svn user trying to recover from brain damage
Date: Fri, 11 May 2007 19:29:31 +0200	[thread overview]
Message-ID: <f228t6$qnq$1@sea.gmane.org> (raw)
In-Reply-To: 92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com

[Cc: Joshua Ball <sciolizer@gmail.com>, git@vger.kernel.org]

Joshua Ball wrote:

> What the heck do these terms mean? The glossary on the Git wiki was
> unhelpful (I'll explain later).

Glossary at GitWiki, http://git.or.cz/gitwiki/GitGlossary is
wikification of "GIT Glossary" from Documentation/glossary.txt
distributed with git-core and installed usually under

  /usr/share/doc/git-core-<version>/glossary.html

but also available at

  http://www.kernel.org/pub/software/scm/git/doc/glossary.html

This wiki page was created for GitWiki to be self contained
(to be able to reference to anchor in GitGlossary when referring
to some term which needs explanation), and also to be able to add
some links to wiki pages in wikified GitGlossary. This wiki page
is probably a bit outdated.

> head
> head ref
> working tree
> object
> branch
> merge
> master
> commit (as in the phrase "bring the working tree to a given commit")
> 
> While the Git wiki does in fact define all of these, it doesn't answer
> any of my questions about those terms:
[cut]

I hope that the following mini-tutorial with some explanations would
help you understand those terms, and clean some SVN misconceptions.


In git history itself is separated from the references to it; when cloning
or fetching from other repository, you get and append missing parts of
history, but the refs on the remote and on local side does not need to
have the same names. In the ascii-art graphs of history objects which
are in "object database" (in history) are on the left, and references
to history are on the right.

 /------ object database -----------\  /------- refs --------\

Let's start with the following history (the following repository
structure)

   A <-- B <-- C <-- D <----------------- master <------- HEAD


$ git branch branchA
(does not change working directory)

   A <-- B <-- C <-- D <----------------- master <------- HEAD
                      \
                       \
                        \--------------- branchA

Branching does not create copy of revisions so far (even if it is
cheap copy like in the case of Subversion). You can always find
the place where branches diverge; it is recorded in repository.
"git merge-base master branchA" returns [id of] revision D.

Creating a branch is just creating a pointer (reference) to some
commit. Head ref, or just a head is this pointer, e.g. 'branchA'
(it resides in  $GIT_DIR/refs/heads/branchA). Commit D is often
called branch tip. Branch as a non-cyclical graph of revisions
is, in the case of 'branchA', branch history of commit D including
this commit, i.e. A<--B<--C<--D DAG.

HEAD (case sensitive, all uppercase) is current branch, usuually
pointer to some other branch.


$ git checkout branchA
(changes working directory, updates HEAD)

   A <-- B <-- C <-- D <----------------- master      /- HEAD
                      \                              /
                       \                            /
                        \--------------- branchA <-/

Those two above steps can be combined to single command
$ git checkout -b branchA


$ edit; edit; ... (changes working directory)
$ git commit -a
(this creates new commit object E, updates branchA ref, i.e.
 ref pointed by HEAD, aka. current branch [head])

   A <-- B <-- C <-- D <----------------- master       /- HEAD
                      \                               /
                       \                             /
                        \- E <----------- branchA <-/

Committing (commit as verb) creates commit object E (commit as noun),
and advances branch head to the newly created commit.


$ git checkout master
$ edit; edit; ...
$ git commit -a

   A <-- B <-- C <-- D <-- F <------------ master <----- HEAD
                      \
                       \
                        \- E <----------- branchA

Note that "git commit" advances current branch head / tip of current
branch, i.e. branch pointed to by HEAD reference.


$ git merge branchA
This does equivalent of doing "diff3 -E F D E", i.e. 3-way merge on
file level, or "diff3 -E HEAD $(git merge-base HEAD branchA) branchA"

   A <-- B <-- C <-- D <-- F <-- G <------ master <----- HEAD
                      \        /
                       \      /
                        \- E- <---------- branchA

Merging (merge as verb) creates merge commit [object] G (merge as noun).
Commit object G has commits G and E as parents (more than one parent).
The information that G is result of merge is recorded in commit
[object] G.


If you have noticed that you want to discard the merge, for example
you don't want to merge yet, i.e. you want to return to state before
merge you can do:

$ git reset --hard ORIG_HEAD
(updates current branch, *does not* update HEAD as a ref,
 contrary to git-checkout)

                           |------\
                           v       \
   A <-- B <-- C <-- D <-- F <-- G  \----- master <----- HEAD
                      \        /
                       \      /
                        \- E- <---------- branchA


Assume situation at the graph before

$ git checkout branchA
$ edit; edit; ...
$ git commit -a
(creates commit H)
$ git checkout master
$ git merge branchA
This time, because merge is recorded as such, the merge base between
'master' branch (branch we merge into) and 'branchA' (branch being
merged) is commit E. Git knows that it has to merge only changes
accumulated since last merge.

   A <-- B <-- C <-- D <-- F <-- G <- J <- master <----- HEAD
                      \        /     /
                       \      /     /
                        \- E-<-- H <------ branchA

 
> In the words of Dijkstra, "Since breaking out of bad habits, rather
> than acquiring new ones, is the toughest part of learning, we must
> expect from that system permanent mental damage for most ... exposed
> to it."
> 
> May you lead me to a quick recovery. Hail to decentralized version control.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

      parent reply	other threads:[~2007-05-11 17:25 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-09 15:30 svn user trying to recover from brain damage Joshua Ball
2007-05-09 16:02 ` Carl Worth
2007-05-09 16:12   ` Karl Hasselström
2007-05-09 16:22 ` Petr Baudis
2007-05-09 20:16   ` Jan Hudec
2007-05-09 16:57 ` Linus Torvalds
2007-05-09 17:43 ` J. Bruce Fields
2007-05-11 17:29 ` Jakub Narebski [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='f228t6$qnq$1@sea.gmane.org' \
    --to=jnareb@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).