X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=Documentation%2Fuser-manual.txt;h=1c49e6995b42e42f1aba4e7b24d073e50c3b5234;hb=3a81b9f571a6b7edd83b3d5f27c3c95d9b1c9d5c;hp=34e965104b892ff0353064f254414cb744da85d4;hpb=77b50ab009deab7f8eb703843a71ac7253b977c8;p=git.git diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 34e965104..1c49e6995 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -288,21 +288,22 @@ collection of files. It stores the history as a compressed collection of interrelated snapshots (versions) of the project's contents. -A single git repository may contain multiple branches. Each branch -is a bookmark referencing a particular point in the project history. -The gitlink:git-branch[1] command shows you the list of branches: +A single git repository may contain multiple branches. It keeps track +of them by keeping a list of <> which reference the +latest version on each branch; the gitlink:git-branch[1] command shows +you the list of branch heads: ------------------------------------------------ $ git branch * master ------------------------------------------------ -A freshly cloned repository contains a single branch, named "master", -and the working directory contains the version of the project -referred to by the master branch. +A freshly cloned repository contains a single branch head, named +"master", and working directory is initialized to the state of +the project referred to by "master". -Most projects also use tags. Tags, like branches, are references -into the project's history, and can be listed using the +Most projects also use <>. Tags, like heads, are +references into the project's history, and can be listed using the gitlink:git-tag[1] command: ------------------------------------------------ @@ -320,9 +321,9 @@ v2.6.13 ------------------------------------------------ Tags are expected to always point at the same version of a project, -while branches are expected to advance as development progresses. +while heads are expected to advance as development progresses. -Create a new branch pointing to one of these versions and check it +Create a new branch head pointing to one of these versions and check it out using gitlink:git-checkout[1]: ------------------------------------------------ @@ -346,10 +347,10 @@ the current branch to point at v2.6.17 instead, with $ git reset --hard v2.6.17 ------------------------------------------------ -Note that if the current branch was your only reference to a +Note that if the current branch head was your only reference to a particular point in history, then resetting that branch may leave you -with no way to find the history it used to point to; so use this -command carefully. +with no way to find the history it used to point to; so use this command +carefully. Understanding History: Commits ------------------------------ @@ -391,15 +392,20 @@ index 8be626f..d7aac9d 100644 As you can see, a commit shows who made the latest change, what they did, and why. -Every commit has a 40-hexdigit id, sometimes called the "object name" -or the "SHA1 id", shown on the first line of the "git show" output. -You can usually refer to a commit by a shorter name, such as a tag or a -branch name, but this longer name can also be useful. Most -importantly, it is a globally unique name for this commit: so if you -tell somebody else the object name (for example in email), then you are -guaranteed that name will refer to the same commit in their repository -that it does in yours (assuming their repository has that commit at -all). +Every commit has a 40-hexdigit id, sometimes called the "object name" or the +"SHA1 id", shown on the first line of the "git show" output. You can usually +refer to a commit by a shorter name, such as a tag or a branch name, but this +longer name can also be useful. Most importantly, it is a globally unique +name for this commit: so if you tell somebody else the object name (for +example in email), then you are guaranteed that name will refer to the same +commit in their repository that it does in yours (assuming their repository +has that commit at all). Since the object name is computed as a hash over the +contents of the commit, you are guaranteed that the commit can never change +without its name also changing. + +In fact, in <> we shall see that everything stored in git +history, including file data and directory contents, is stored in an object +with a name that is a hash of its contents. Understanding history: commits, parents, and reachability ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -432,11 +438,14 @@ We will sometimes represent git history using diagrams like the one below. Commits are shown as "o", and the links between them with lines drawn with - / and \. Time goes left to right: + +................................................ o--o--o <-- Branch A / o--o--o <-- master \ o--o--o <-- Branch B +................................................ If we need to talk about a particular commit, the character "o" may be replaced with another letter or number. @@ -444,17 +453,15 @@ be replaced with another letter or number. Understanding history: What is a branch? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Though we've been using the word "branch" to mean a kind of reference -to a particular commit, the word branch is also commonly used to -refer to the line of commits leading up to that point. In the -example above, git may think of the branch named "A" as just a -pointer to one particular commit, but we may refer informally to the -line of three commits leading up to that point as all being part of +When we need to be precise, we will use the word "branch" to mean a line +of development, and "branch head" (or just "head") to mean a reference +to the most recent commit on a branch. In the example above, the branch +head named "A" is a pointer to one particular commit, but we refer to +the line of three commits leading up to that point as all being part of "branch A". -If we need to make it clear that we're just talking about the most -recent commit on the branch, we may refer to that commit as the -"head" of the branch. +However, when no confusion will result, we often just use the term +"branch" both for branches and for branch heads. Manipulating branches --------------------- @@ -596,8 +603,8 @@ a new stanza: $ cat .git/config ... [remote "linux-nfs"] - url = git://linux-nfs.org/~bfields/git.git - fetch = +refs/heads/*:refs/remotes/linux-nfs-read/* + url = git://linux-nfs.org/pub/nfs-2.6.git + fetch = +refs/heads/*:refs/remotes/linux-nfs/* ... ------------------------------------------------- @@ -1128,17 +1135,9 @@ modified in two different ways in the remote branch and the local branch--then you are warned; the output may look something like this: ------------------------------------------------- -$ git pull . next -Trying really trivial in-index merge... -fatal: Merge requires file-level merging -Nope. -Merging HEAD with 77976da35a11db4580b80ae27e8d65caf5208086 -Merging: -15e2162 world -77976da goodbye -found 1 common ancestor(s): -d122ed4 initial -Auto-merging file.txt +$ git merge next + 100% (4/4) done +Auto-merged file.txt CONFLICT (content): Merge conflict in file.txt Automatic merge failed; fix conflicts and then commit the result. ------------------------------------------------- @@ -1163,18 +1162,46 @@ the working tree in a special state that gives you all the information you need to help resolve the merge. Files with conflicts are marked specially in the index, so until you -resolve the problem and update the index, git commit will fail: +resolve the problem and update the index, gitlink:git-commit[1] will +fail: ------------------------------------------------- $ git commit file.txt: needs merge ------------------------------------------------- -Also, git status will list those files as "unmerged". +Also, gitlink:git-status[1] will list those files as "unmerged", and the +files with conflicts will have conflict markers added, like this: + +------------------------------------------------- +<<<<<<< HEAD:file.txt +Hello world +======= +Goodbye +>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt +------------------------------------------------- + +All you need to do is edit the files to resolve the conflicts, and then + +------------------------------------------------- +$ git add file.txt +$ git commit +------------------------------------------------- + +Note that the commit message will already be filled in for you with +some information about the merge. Normally you can just use this +default message unchanged, but you may add additional commentary of +your own if desired. + +The above is all you need to know to resolve a simple merge. But git +also provides more information to help resolve conflicts: + +Getting conflict-resolution help during a merge +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All of the changes that git was able to merge automatically are already added to the index file, so gitlink:git-diff[1] shows only -the conflicts. Also, it uses a somewhat unusual syntax: +the conflicts. It uses an unusual syntax: ------------------------------------------------- $ git diff @@ -1195,14 +1222,32 @@ conflict will have two parents instead of the usual one: one parent will be HEAD, the tip of the current branch; the other will be the tip of the other branch, which is stored temporarily in MERGE_HEAD. -The diff above shows the differences between the working-tree version -of file.txt and two previous versions: one version from HEAD, and one -from MERGE_HEAD. So instead of preceding each line by a single "+" -or "-", it now uses two columns: the first column is used for -differences between the first parent and the working directory copy, -and the second for differences between the second parent and the -working directory copy. Thus after resolving the conflict in the -obvious way, the diff will look like: +During the merge, the index holds three versions of each file. Each of +these three "file stages" represents a different version of the file: + +------------------------------------------------- +$ git show :1:file.txt # the file in a common ancestor of both branches +$ git show :2:file.txt # the version from HEAD, but including any + # nonconflicting changes from MERGE_HEAD +$ git show :3:file.txt # the version from MERGE_HEAD, but including any + # nonconflicting changes from HEAD. +------------------------------------------------- + +Since the stage 2 and stage 3 versions have already been updated with +nonconflicting changes, the only remaining differences between them are +the important ones; thus gitlink:git-diff[1] can use the information in +the index to show only those conflicts. + +The diff above shows the differences between the working-tree version of +file.txt and the stage 2 and stage 3 versions. So instead of preceding +each line by a single "+" or "-", it now uses two columns: the first +column is used for differences between the first parent and the working +directory copy, and the second for differences between the second parent +and the working directory copy. (See the "COMBINED DIFF FORMAT" section +of gitlink:git-diff-files[1] for a details of the format.) + +After resolving the conflict in the obvious way (but before updating the +index), the diff will look like: ------------------------------------------------- $ git diff @@ -1220,26 +1265,37 @@ This shows that our resolved version deleted "Hello world" from the first parent, deleted "Goodbye" from the second parent, and added "Goodbye world", which was previously absent from both. -The gitlink:git-log[1] command also provides special help for merges: +Some special diff options allow diffing the working directory against +any of these stages: + +------------------------------------------------- +$ git diff -1 file.txt # diff against stage 1 +$ git diff --base file.txt # same as the above +$ git diff -2 file.txt # diff against stage 2 +$ git diff --ours file.txt # same as the above +$ git diff -3 file.txt # diff against stage 3 +$ git diff --theirs file.txt # same as the above. +------------------------------------------------- + +The gitlink:git-log[1] and gitk[1] commands also provide special help +for merges: ------------------------------------------------- $ git log --merge +$ gitk --merge ------------------------------------------------- -This will list all commits which exist only on HEAD or on MERGE_HEAD, -and which touch an unmerged file. +These will display all commits which exist only on HEAD or on +MERGE_HEAD, and which touch an unmerged file. -We can now add the resolved version to the index and commit: +Each time you resolve the conflicts in a file and update the index: ------------------------------------------------- $ git add file.txt -$ git commit ------------------------------------------------- -Note that the commit message will already be filled in for you with -some information about the merge. Normally you can just use this -default message unchanged, but you may add additional commentary of -your own if desired. +the different stages of that file will be "collapsed", after which +git-diff will (by default) no longer show diffs for that file. [[undoing-a-merge]] undoing a merge @@ -1255,7 +1311,7 @@ $ git reset --hard HEAD Or, if you've already commited the merge that you want to throw away, ------------------------------------------------- -$ git reset --hard HEAD^ +$ git reset --hard ORIG_HEAD ------------------------------------------------- However, this last command can be dangerous in some cases--never @@ -1328,6 +1384,7 @@ with the changes to be reverted, then you will be asked to fix conflicts manually, just as in the case of <>. +[[fixing-a-mistake-by-editing-history]] Fixing a mistake by editing history ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1376,7 +1433,7 @@ modifying the working directory, you can do that with gitlink:git-show[1]: ------------------------------------------------- -$ git show HEAD^ path/to/file +$ git show HEAD^:path/to/file ------------------------------------------------- which will display the given version of the file. @@ -1640,7 +1697,7 @@ If you and maintainer both have accounts on the same machine, then then you can just pull changes from each other's repositories directly; note that all of the commands (gitlink:git-clone[1], git-fetch[1], git-pull[1], etc.) that accept a URL as an argument -will also accept a local file patch; so, for example, you can +will also accept a local directory name; so, for example, you can use ------------------------------------------------- @@ -1873,25 +1930,29 @@ $ git commit You have performed no merges into mywork, so it is just a simple linear sequence of patches on top of "origin": - +................................................ o--o--o <-- origin \ o--o--o <-- mywork +................................................ Some more interesting work has been done in the upstream project, and "origin" has advanced: +................................................ o--o--O--o--o--o <-- origin \ a--b--c <-- mywork +................................................ At this point, you could use "pull" to merge your changes back in; the result would create a new merge commit, like this: - +................................................ o--o--O--o--o--o <-- origin \ \ a--b--c--m <-- mywork +................................................ However, if you prefer to keep the history in mywork a simple series of commits without any merges, you may instead choose to use @@ -1908,9 +1969,11 @@ point at the latest version of origin, then apply each of the saved patches to the new mywork. The result will look like: +................................................ o--o--O--o--o--o <-- origin \ a'--b'--c' <-- mywork +................................................ In the process, it may discover conflicts. In that case it will stop and allow you to fix the conflicts; after fixing conflicts, use "git @@ -1930,6 +1993,51 @@ return mywork to the state it had before you started the rebase: $ git rebase --abort ------------------------------------------------- +Modifying a single commit +------------------------- + +We saw in <> that you can replace the +most recent commit using + +------------------------------------------------- +$ git commit --amend +------------------------------------------------- + +which will replace the old commit by a new commit incorporating your +changes, giving you a chance to edit the old commit message first. + +You can also use a combination of this and gitlink:git-rebase[1] to edit +commits further back in your history. First, tag the problematic commit with + +------------------------------------------------- +$ git tag bad mywork~5 +------------------------------------------------- + +(Either gitk or git-log may be useful for finding the commit.) + +Then check out a new branch at that commit, edit it, and rebase the rest of +the series on top of it: + +------------------------------------------------- +$ git checkout -b TMP bad +$ # make changes here and update the index +$ git commit --amend +$ git rebase --onto TMP bad mywork +------------------------------------------------- + +When you're done, you'll be left with mywork checked out, with the top patches +on mywork reapplied on top of the modified commit you created in TMP. You can +then clean up with + +------------------------------------------------- +$ git branch -d TMP +$ git tag -d bad +------------------------------------------------- + +Note that the immutable nature of git history means that you haven't really +"modified" existing commits; instead, you have replaced the old commits with +new commits having new object names. + Reordering or selecting from a patch series ------------------------------------------- @@ -1973,24 +2081,30 @@ The primary problem with rewriting the history of a branch has to do with merging. Suppose somebody fetches your branch and merges it into their branch, with a result something like this: +................................................ o--o--O--o--o--o <-- origin \ \ t--t--t--m <-- their branch: +................................................ Then suppose you modify the last three commits: +................................................ o--o--o <-- new head of origin / o--o--O--o--o--o <-- old head of origin +................................................ If we examined all this history together in one repository, it will look like: +................................................ o--o--o <-- new head of origin / o--o--O--o--o--o <-- old head of origin \ \ t--t--t--m <-- their branch: +................................................ Git has no way of knowing that the new head is an updated version of the old head; it treats this situation exactly the same as it would if @@ -2051,9 +2165,11 @@ commit. Git calls this process a "fast forward". A fast forward looks something like this: +................................................ o--o--o--o <-- old head of the branch \ o--o--o <-- new head of the branch +................................................ In some cases it is possible that the new head will *not* actually be @@ -2061,11 +2177,11 @@ a descendant of the old head. For example, the developer may have realized she made a serious mistake, and decided to backtrack, resulting in a situation like: +................................................ o--o--o--o--a--b <-- old head of the branch \ o--o--o <-- new head of the branch - - +................................................ In this case, "git fetch" will fail, and print out a warning. @@ -2155,6 +2271,7 @@ See gitlink:git-config[1] for more details on the configuration options mentioned above. +[[git-internals]] Git internals ============= @@ -2895,9 +3012,6 @@ confusing and scary messages, but it won't actually do anything bad. In contrast, running "git prune" while somebody is actively changing the repository is a *BAD* idea). -Glossary of git terms -===================== - include::glossary.txt[] Notes and todo list for this manual @@ -2936,11 +3050,6 @@ provides. Simplify beginning by suggesting disconnected head instead of temporary branch creation? -Explain how to refer to file stages in the "how to resolve a merge" -section: diff -1, -2, -3, --ours, --theirs :1:/path notation. The -"git ls-files --unmerged --stage" thing is sorta useful too, -actually. And note gitk --merge. - Add more good examples. Entire sections of just cookbook examples might be a good idea; maybe make an "advanced examples" section a standard end-of-chapter section?