[Cc: Joshua Ball <sciolizer@xxxxxxxxx>, git@xxxxxxxxxxxxxxx] 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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html