Merge branch 'ph/parseopt-sh'
[gitweb.git] / Documentation / core-tutorial.txt
index 97cdb90cb4e5763a4d0cec1a0d01f5380b4e512f..bd6cd4124546a867c029a0c14b16f1944f9eca88 100644 (file)
@@ -4,34 +4,24 @@ A git core tutorial for developers
 Introduction
 ------------
 
-This is trying to be a short tutorial on setting up and using a git
-repository, mainly because being hands-on and using explicit examples is
-often the best way of explaining what is going on.
+This tutorial explains how to use the "core" git programs to set up and
+work with a git repository.
 
-In normal life, most people wouldn't use the "core" git programs
-directly, but rather script around them to make them more palatable. 
-Understanding the core git stuff may help some people get those scripts
-done, though, and it may also be instructive in helping people
-understand what it is that the higher-level helper scripts are actually
-doing. 
+If you just need to use git as a revision control system you may prefer
+to start with link:tutorial.html[a tutorial introduction to git] or
+link:user-manual.html[the git user manual].
+
+However, an understanding of these low-level tools can be helpful if
+you want to understand git's internals.
 
 The core git is often called "plumbing", with the prettier user
 interfaces on top of it called "porcelain". You may not want to use the
 plumbing directly very often, but it can be good to know what the
 plumbing does for when the porcelain isn't flushing.
 
-The material presented here often goes deep describing how things
-work internally.  If you are mostly interested in using git as a
-SCM, you can skip them during your first pass.
-
-[NOTE]
-And those "too deep" descriptions are often marked as Note.
-
 [NOTE]
-If you are already familiar with another version control system,
-like CVS, you may want to take a look at
-link:everyday.html[Everyday GIT in 20 commands or so] first
-before reading this.
+Deeper technical details are often marked as Notes, which you can
+skip on your first reading.
 
 
 Creating a git repository
@@ -41,7 +31,7 @@ Creating a new git repository couldn't be easier: all git repositories start
 out empty, and the only thing you need to do is find yourself a
 subdirectory that you want to use as a working tree - either an empty
 one for a totally new project, or an existing working tree that you want
-to import into git. 
+to import into git.
 
 For our first example, we're going to start a totally new repository from
 scratch, with no pre-existing files, and we'll call it `git-tutorial`.
@@ -169,7 +159,7 @@ $ ls .git/objects/??/*
 and see two files:
 
 ----------------
-.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 
+.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238
 .git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962
 ----------------
 
@@ -220,7 +210,7 @@ you have not actually really "checked in" your files into git so far,
 you've only *told* git about them.
 
 However, since git knows about them, you can now start using some of the
-most basic git commands to manipulate the files or look at their status. 
+most basic git commands to manipulate the files or look at their status.
 
 In particular, let's not even check in the two files into git yet, we'll
 start off by adding another line to `hello` first:
@@ -319,10 +309,9 @@ argument to `git-commit-tree`.
 `git-commit-tree` normally takes several arguments -- it wants to know
 what the 'parent' of a commit was, but since this is the first commit
 ever in this new repository, and it has no parents, we only need to pass in
-the object name of the tree. However, `git-commit-tree`
-also wants to get a commit message
-on its standard input, and it will write out the resulting object name for the
-commit to its standard output.
+the object name of the tree. However, `git-commit-tree` also wants to get a
+commit message on its standard input, and it will write out the resulting
+object name for the commit to its standard output.
 
 And this is where we create the `.git/refs/heads/master` file
 which is pointed at by `HEAD`. This file is supposed to contain
@@ -351,7 +340,7 @@ Making a change
 
 Remember how we did the `git-update-index` on file `hello` and then we
 changed `hello` afterward, and could compare the new state of `hello` with the
-state we saved in the index file? 
+state we saved in the index file?
 
 Further, remember how I said that `git-write-tree` writes the contents
 of the *index* file to the tree, and thus what we just committed was in
@@ -371,7 +360,7 @@ file and the working tree, `git-diff-index` shows the differences
 between a committed *tree* and either the index file or the working
 tree. In other words, `git-diff-index` wants a tree to be diffed
 against, and before we did the commit, we couldn't do that, because we
-didn't have anything to diff against. 
+didn't have anything to diff against.
 
 But now we can do
 
@@ -380,7 +369,7 @@ $ git-diff-index -p HEAD
 ----------------
 
 (where `-p` has the same meaning as it did in `git-diff-files`), and it
-will show us the same difference, but for a totally different reason. 
+will show us the same difference, but for a totally different reason.
 Now we're comparing the working tree not against the index file,
 but against the tree we just wrote. It just so happens that those two
 are obviously the same, so we get the same result.
@@ -399,7 +388,7 @@ working tree, but when given the `\--cached` flag, it is told to
 instead compare against just the index cache contents, and ignore the
 current working tree state entirely. Since we just wrote the index
 file to HEAD, doing `git-diff-index \--cached -p HEAD` should thus return
-an empty set of differences, and that's exactly what it does. 
+an empty set of differences, and that's exactly what it does.
 
 [NOTE]
 ================
@@ -550,7 +539,7 @@ $ git-whatchanged -p --root
 ----------------
 
 and you will see exactly what has changed in the repository over its
-short history. 
+short history.
 
 [NOTE]
 The `\--root` flag is a flag to `git-diff-tree` to tell it to
@@ -564,13 +553,8 @@ can explore on your own.
 
 [NOTE]
 Most likely, you are not directly using the core
-git Plumbing commands, but using Porcelain like Cogito on top
-of it. Cogito works a bit differently and you usually do not
-have to run `git-update-index` yourself for changed files (you
-do tell underlying git about additions and removals via
-`cg-add` and `cg-rm` commands). Just before you make a commit
-with `cg-commit`, Cogito figures out which files you modified,
-and runs `git-update-index` on them for you.
+git Plumbing commands, but using Porcelain such as `git-add`, `git-rm'
+and `git-commit'.
 
 
 Tagging a version
@@ -638,7 +622,7 @@ So the mental model of "the git information is always tied directly to
 the working tree that it describes" may not be technically 100%
 accurate, but it's a good model for all normal use.
 
-This has two implications: 
+This has two implications:
 
  - if you grow bored with the tutorial repository you created (or you've
    made a mistake and want to start all over), you can just do simple
@@ -697,8 +681,8 @@ $ git reset
 
 and in fact a lot of the common git command combinations can be scripted
 with the `git xyz` interfaces.  You can learn things by just looking
-at what the various git scripts do.  For example, `git reset` is the
-above two lines implemented in `git-reset`, but some things like
+at what the various git scripts do.  For example, `git reset` used to be
+the above two lines implemented in `git-reset`, but some things like
 `git status` and `git commit` are slightly more complex scripts around
 the basic git commands.
 
@@ -706,7 +690,7 @@ Many (most?) public remote repositories will not contain any of
 the checked out files or even an index file, and will *only* contain the
 actual core git files. Such a repository usually doesn't even have the
 `.git` subdirectory, but has all the git files directly in the
-repository. 
+repository.
 
 To create your own local live copy of such a "raw" git repository, you'd
 first create your own subdirectory for the project, and then copy the
@@ -719,7 +703,7 @@ $ cd my-git
 $ rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git
 ----------------
 
-followed by 
+followed by
 
 ----------------
 $ git-read-tree HEAD
@@ -739,7 +723,7 @@ up-to-date (so that you don't have to refresh it afterward), and the
 `-a` flag means "check out all files" (if you have a stale copy or an
 older version of a checked out tree you may also need to add the `-f`
 flag first, to tell git-checkout-index to *force* overwriting of any old
-files). 
+files).
 
 Again, this can all be simplified with
 
@@ -752,7 +736,7 @@ $ git checkout
 which will end up doing all of the above for you.
 
 You have now successfully copied somebody else's (mine) remote
-repository, and checked it out. 
+repository, and checked it out.
 
 
 Creating a new branch
@@ -761,14 +745,14 @@ Creating a new branch
 Branches in git are really nothing more than pointers into the git
 object database from within the `.git/refs/` subdirectory, and as we
 already discussed, the `HEAD` branch is nothing but a symlink to one of
-these object pointers. 
+these object pointers.
 
 You can at any time create a new branch by just picking an arbitrary
 point in the project history, and just writing the SHA1 name of that
 object into a file under `.git/refs/heads/`. You can use any filename you
 want (and indeed, subdirectories), but the convention is that the
 "normal" branch is called `master`. That's just a convention, though,
-and nothing enforces it. 
+and nothing enforces it.
 
 To show that as an example, let's go back to the git-tutorial repository we
 used earlier, and create a branch in it. You do that by simply just
@@ -779,7 +763,7 @@ $ git checkout -b mybranch
 ------------
 
 will create a new branch based at the current `HEAD` position, and switch
-to it. 
+to it.
 
 [NOTE]
 ================================================
@@ -816,8 +800,8 @@ you have, you can say
 $ git branch
 ------------
 
-which is nothing more than a simple script around `ls .git/refs/heads`.
-There will be asterisk in front of the branch you are currently on.
+which used to be nothing more than a simple script around `ls .git/refs/heads`.
+There will be an asterisk in front of the branch you are currently on.
 
 Sometimes you may wish to create a new branch _without_ actually
 checking it out and switching to it. If so, just use the command
@@ -826,7 +810,7 @@ checking it out and switching to it. If so, just use the command
 $ git branch <branchname> [startingpoint]
 ------------
 
-which will simply _create_ the branch, but will not do anything further. 
+which will simply _create_ the branch, but will not do anything further.
 You can then later -- once you decide that you want to actually develop
 on that branch -- switch to that branch with a regular `git checkout`
 with the branchname as the argument.
@@ -844,7 +828,7 @@ that branch, and do some work there.
 ------------------------------------------------
 $ git checkout mybranch
 $ echo "Work, work, work" >>hello
-$ git commit -m 'Some work.' -i hello
+$ git commit -m "Some work." -i hello
 ------------------------------------------------
 
 Here, we just added another line to `hello`, and we used a shorthand for
@@ -869,7 +853,7 @@ hasn't happened in the `master` branch at all. Then do
 ------------
 $ echo "Play, play, play" >>hello
 $ echo "Lots of fun" >>example
-$ git commit -m 'Some fun.' -i hello example
+$ git commit -m "Some fun." -i hello example
 ------------
 
 since the master branch is obviously in a much better mood.
@@ -885,7 +869,7 @@ $ gitk --all
 will show you graphically both of your branches (that's what the `\--all`
 means: normally it will just show you your current `HEAD`) and their
 histories. You can also see exactly how they came to be from a common
-source. 
+source.
 
 Anyway, let's exit `gitk` (`^Q` or the File menu), and decide that we want
 to merge the work we did on the `mybranch` branch into the `master`
@@ -894,7 +878,7 @@ script called `git merge`, which wants to know which branches you want
 to resolve and what the merge is all about:
 
 ------------
-$ git merge "Merge work in mybranch" HEAD mybranch
+$ git merge -m "Merge work in mybranch" mybranch
 ------------
 
 where the first argument is going to be used as the commit message if
@@ -906,8 +890,8 @@ of it as it can automatically (which in this case is just merge the `example`
 file, which had no differences in the `mybranch` branch), and say:
 
 ----------------
-       Auto-merging hello 
-       CONFLICT (content): Merge conflict in hello 
+       Auto-merging hello
+       CONFLICT (content): Merge conflict in hello
        Automatic merge failed; fix up by hand
 ----------------
 
@@ -947,12 +931,13 @@ Another useful tool, especially if you do not always work in X-Window
 environment, is `git show-branch`.
 
 ------------------------------------------------
-$ git show-branch --topo-order master mybranch
+$ git-show-branch --topo-order --more=1 master mybranch
 * [master] Merge work in mybranch
  ! [mybranch] Some work.
 --
 -  [master] Merge work in mybranch
 *+ [mybranch] Some work.
+*  [master^] Some fun.
 ------------------------------------------------
 
 The first two lines indicate that it is showing the two branches
@@ -963,17 +948,29 @@ the later output lines is used to show commits contained in the
 `master` branch, and the second column for the `mybranch`
 branch. Three commits are shown along with their log messages.
 All of them have non blank characters in the first column (`*`
-shows an ordinary commit on the current branch, `.` is a merge commit), which
+shows an ordinary commit on the current branch, `-` is a merge commit), which
 means they are now part of the `master` branch. Only the "Some
 work" commit has the plus `+` character in the second column,
 because `mybranch` has not been merged to incorporate these
 commits from the master branch.  The string inside brackets
 before the commit log message is a short name you can use to
 name the commit.  In the above example, 'master' and 'mybranch'
-are branch heads.  'master~1' is the first parent of 'master'
+are branch heads.  'master^' is the first parent of 'master'
 branch head.  Please see 'git-rev-parse' documentation if you
 see more complex cases.
 
+[NOTE]
+Without the '--more=1' option, 'git-show-branch' would not output the
+'[master^]' commit, as '[mybranch]' commit is a common ancestor of
+both 'master' and 'mybranch' tips.  Please see 'git-show-branch'
+documentation for details.
+
+[NOTE]
+If there were more commits on the 'master' branch after the merge, the
+merge commit itself would not be shown by 'git-show-branch' by
+default.  You would need to provide '--sparse' option to make the
+merge commit visible in this case.
+
 Now, let's pretend you are the one who did all the work in
 `mybranch`, and the fruit of your hard work has finally been merged
 to the `master` branch. Let's go back to `mybranch`, and run
@@ -981,7 +978,7 @@ to the `master` branch. Let's go back to `mybranch`, and run
 
 ------------
 $ git checkout mybranch
-$ git merge "Merge upstream changes." HEAD master
+$ git merge -m "Merge upstream changes." master
 ------------
 
 This outputs something like this (the actual commit object names
@@ -1093,11 +1090,6 @@ server like git Native transport does.  Any stock HTTP server
 that does not even support directory index would suffice.  But
 you must prepare your repository with `git-update-server-info`
 to help dumb transport downloaders.
-+
-There are (confusingly enough) `git-ssh-fetch` and `git-ssh-upload`
-programs, which are 'commit walkers'; they outlived their
-usefulness when git Native and SSH transports were introduced,
-and not used by `git pull` or `git push` scripts.
 
 Once you fetch from the remote repository, you `merge` that
 with your current branch.
@@ -1160,7 +1152,7 @@ back to the earlier repository with "hello" and "example" file,
 and bring ourselves back to the pre-merge state:
 
 ------------
-$ git show-branch --more=3 master mybranch
+$ git show-branch --more=2 master mybranch
 ! [master] Merge work in mybranch
  * [mybranch] Merge work in mybranch
 --
@@ -1204,7 +1196,7 @@ $ mb=$(git-merge-base HEAD mybranch)
 
 The command writes the commit object name of the common ancestor
 to the standard output, so we captured its output to a variable,
-because we will be using it in the next step.  BTW, the common
+because we will be using it in the next step.  By the way, the common
 ancestor commit is the "New day." commit in this case.  You can
 tell it by:
 
@@ -1223,7 +1215,7 @@ $ git-read-tree -m -u $mb HEAD mybranch
 This is the same `git-read-tree` command we have already seen,
 but it takes three trees, unlike previous examples.  This reads
 the contents of each tree into different 'stage' in the index
-file (the first tree goes to stage 1, the second stage 2,
+file (the first tree goes to stage 1, the second to stage 2,
 etc.).  After reading three trees into three stages, the paths
 that are the same in all three stages are 'collapsed' into stage
 0.  Also paths that are the same in two of three stages are
@@ -1304,7 +1296,7 @@ So, we can use somebody else's work from a remote repository, but
 how can *you* prepare a repository to let other people pull from
 it?
 
-Your do your real work in your working tree that has your
+You do your real work in your working tree that has your
 primary repository hanging under it as its `.git` subdirectory.
 You *could* make that repository accessible remotely and ask
 people to pull from it, but in practice that is not the way
@@ -1388,7 +1380,7 @@ repository. Kernel.org mirror network takes care of the
 propagation to other publicly visible machines:
 
 ------------
-$ git push master.kernel.org:/pub/scm/git/git.git/ 
+$ git push master.kernel.org:/pub/scm/git/git.git/
 ------------
 
 
@@ -1470,7 +1462,7 @@ Although git is a truly distributed system, it is often
 convenient to organize your project with an informal hierarchy
 of developers. Linux kernel development is run this way. There
 is a nice illustration (page 17, "Merges to Mainline") in
-link:http://tinyurl.com/a2jdg[Randy Dunlap's presentation].
+link:http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf[Randy Dunlap's presentation].
 
 It should be stressed that this hierarchy is purely *informal*.
 There is nothing fundamental in git that enforces the "chain of
@@ -1623,8 +1615,8 @@ in both of them.  You could merge in 'diff-fix' first and then
 'commit-fix' next, like this:
 
 ------------
-$ git merge 'Merge fix in diff-fix' master diff-fix
-$ git merge 'Merge fix in commit-fix' master commit-fix
+$ git merge -m "Merge fix in diff-fix" diff-fix
+$ git merge -m "Merge fix in commit-fix" commit-fix
 ------------
 
 Which would result in:
@@ -1687,5 +1679,3 @@ merge two at a time, documenting how you resolved the conflicts,
 and the reason why you preferred changes made in one side over
 the other.  Otherwise it would make the project history harder
 to follow, not easier.
-
-[ to be continued.. cvsimports ]