Merge branch 'maint'
* maint: user-manual: recovering from corruption user-manual: clarify language about "modifying" old commits user-manual: failed push to public repository user-manual: define "branch" and "working tree" at start git-checkout: describe detached head correctly
This commit is contained in:
		| @ -56,11 +56,12 @@ $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git | |||||||
| The initial clone may be time-consuming for a large project, but you | The initial clone may be time-consuming for a large project, but you | ||||||
| will only need to clone once. | will only need to clone once. | ||||||
|  |  | ||||||
| The clone command creates a new directory named after the project | The clone command creates a new directory named after the project ("git" | ||||||
| ("git" or "linux-2.6" in the examples above).  After you cd into this | or "linux-2.6" in the examples above).  After you cd into this | ||||||
| directory, you will see that it contains a copy of the project files, | directory, you will see that it contains a copy of the project files, | ||||||
| together with a special top-level directory named ".git", which | called the <<def_working_tree,working tree>>, together with a special | ||||||
| contains all the information about the history of the project. | top-level directory named ".git", which contains all the information | ||||||
|  | about the history of the project. | ||||||
|  |  | ||||||
| [[how-to-check-out]] | [[how-to-check-out]] | ||||||
| How to check out a different version of a project | How to check out a different version of a project | ||||||
| @ -71,8 +72,13 @@ of files.  It stores the history as a compressed collection of | |||||||
| interrelated snapshots of the project's contents.  In git each such | interrelated snapshots of the project's contents.  In git each such | ||||||
| version is called a <<def_commit,commit>>. | version is called a <<def_commit,commit>>. | ||||||
|  |  | ||||||
| A single git repository may contain multiple branches.  It keeps track | Those snapshots aren't necessarily all arranged in a single line from | ||||||
| of them by keeping a list of <<def_head,heads>> which reference the | oldest to newest; instead, work may simultaneously proceed along | ||||||
|  | parallel lines of development, called <def_branch,branches>>, which may | ||||||
|  | merge and diverge. | ||||||
|  |  | ||||||
|  | A single git repository can track development on multiple branches.  It | ||||||
|  | does this by keeping a list of <<def_head,heads>> which reference the | ||||||
| latest commit on each branch; the gitlink:git-branch[1] command shows | latest commit on each branch; the gitlink:git-branch[1] command shows | ||||||
| you the list of branch heads: | you the list of branch heads: | ||||||
|  |  | ||||||
| @ -1410,8 +1416,8 @@ with the changes to be reverted, then you will be asked to fix | |||||||
| conflicts manually, just as in the case of <<resolving-a-merge, | conflicts manually, just as in the case of <<resolving-a-merge, | ||||||
| resolving a merge>>. | resolving a merge>>. | ||||||
|  |  | ||||||
| [[fixing-a-mistake-by-editing-history]] | [[fixing-a-mistake-by-rewriting-history]] | ||||||
| Fixing a mistake by editing history | Fixing a mistake by rewriting history | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
| If the problematic commit is the most recent commit, and you have not | If the problematic commit is the most recent commit, and you have not | ||||||
| @ -1434,7 +1440,7 @@ Again, you should never do this to a commit that may already have | |||||||
| been merged into another branch; use gitlink:git-revert[1] instead in | been merged into another branch; use gitlink:git-revert[1] instead in | ||||||
| that case. | that case. | ||||||
|  |  | ||||||
| It is also possible to edit commits further back in the history, but | It is also possible to replace commits further back in the history, but | ||||||
| this is an advanced topic to be left for | this is an advanced topic to be left for | ||||||
| <<cleaning-up-history,another chapter>>. | <<cleaning-up-history,another chapter>>. | ||||||
|  |  | ||||||
| @ -1554,6 +1560,11 @@ This may be time-consuming.  Unlike most other git operations (including | |||||||
| git-gc when run without any options), it is not safe to prune while | git-gc when run without any options), it is not safe to prune while | ||||||
| other git operations are in progress in the same repository. | other git operations are in progress in the same repository. | ||||||
|  |  | ||||||
|  | If gitlink:git-fsck[1] complains about sha1 mismatches or missing | ||||||
|  | objects, you may have a much more serious problem; your best option is | ||||||
|  | probably restoring from backups.  See | ||||||
|  | <<recovering-from-repository-corruption>> for a detailed discussion. | ||||||
|  |  | ||||||
| [[recovering-lost-changes]] | [[recovering-lost-changes]] | ||||||
| Recovering lost changes | Recovering lost changes | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
| @ -1923,15 +1934,9 @@ or just | |||||||
| $ git push ssh://yourserver.com/~you/proj.git master | $ git push ssh://yourserver.com/~you/proj.git master | ||||||
| ------------------------------------------------- | ------------------------------------------------- | ||||||
|  |  | ||||||
| As with git-fetch, git-push will complain if this does not result in | As with git-fetch, git-push will complain if this does not result in a | ||||||
| a <<fast-forwards,fast forward>>.  Normally this is a sign of | <<fast-forwards,fast forward>>; see the following section for details on | ||||||
| something wrong.  However, if you are sure you know what you're | handling this case. | ||||||
| doing, you may force git-push to perform the update anyway by |  | ||||||
| preceding the branch name by a plus sign: |  | ||||||
|  |  | ||||||
| ------------------------------------------------- |  | ||||||
| $ git push ssh://yourserver.com/~you/proj.git +master |  | ||||||
| ------------------------------------------------- |  | ||||||
|  |  | ||||||
| Note that the target of a "push" is normally a | Note that the target of a "push" is normally a | ||||||
| <<def_bare_repository,bare>> repository.  You can also push to a | <<def_bare_repository,bare>> repository.  You can also push to a | ||||||
| @ -1959,6 +1964,52 @@ See the explanations of the remote.<name>.url, branch.<name>.remote, | |||||||
| and remote.<name>.push options in gitlink:git-config[1] for | and remote.<name>.push options in gitlink:git-config[1] for | ||||||
| details. | details. | ||||||
|  |  | ||||||
|  | [[forcing-push]] | ||||||
|  | What to do when a push fails | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | If a push would not result in a <<fast-forwards,fast forward>> of the | ||||||
|  | remote branch, then it will fail with an error like: | ||||||
|  |  | ||||||
|  | ------------------------------------------------- | ||||||
|  | error: remote 'refs/heads/master' is not an ancestor of | ||||||
|  |  local  'refs/heads/master'. | ||||||
|  |  Maybe you are not up-to-date and need to pull first? | ||||||
|  | error: failed to push to 'ssh://yourserver.com/~you/proj.git' | ||||||
|  | ------------------------------------------------- | ||||||
|  |  | ||||||
|  | This can happen, for example, if you: | ||||||
|  |  | ||||||
|  | 	- use `git reset --hard` to remove already-published commits, or | ||||||
|  | 	- use `git commit --amend` to replace already-published commits | ||||||
|  | 	  (as in <<fixing-a-mistake-by-rewriting-history>>), or | ||||||
|  | 	- use `git rebase` to rebase any already-published commits (as | ||||||
|  | 	  in <<using-git-rebase>>). | ||||||
|  |  | ||||||
|  | You may force git-push to perform the update anyway by preceding the | ||||||
|  | branch name with a plus sign: | ||||||
|  |  | ||||||
|  | ------------------------------------------------- | ||||||
|  | $ git push ssh://yourserver.com/~you/proj.git +master | ||||||
|  | ------------------------------------------------- | ||||||
|  |  | ||||||
|  | Normally whenever a branch head in a public repository is modified, it | ||||||
|  | is modified to point to a descendent of the commit that it pointed to | ||||||
|  | before.  By forcing a push in this situation, you break that convention. | ||||||
|  | (See <<problems-with-rewriting-history>>.) | ||||||
|  |  | ||||||
|  | Nevertheless, this is a common practice for people that need a simple | ||||||
|  | way to publish a work-in-progress patch series, and it is an acceptable | ||||||
|  | compromise as long as you warn other developers that this is how you | ||||||
|  | intend to manage the branch. | ||||||
|  |  | ||||||
|  | It's also possible for a push to fail in this way when other people have | ||||||
|  | the right to push to the same repository.  In that case, the correct | ||||||
|  | solution is to retry the push after first updating your work by either a | ||||||
|  | pull or a fetch followed by a rebase; see the | ||||||
|  | <<setting-up-a-shared-repository,next section>> and | ||||||
|  | link:cvs-migration.html[git for CVS users] for more. | ||||||
|  |  | ||||||
| [[setting-up-a-shared-repository]] | [[setting-up-a-shared-repository]] | ||||||
| Setting up a shared repository | Setting up a shared repository | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
| @ -2426,11 +2477,11 @@ return mywork to the state it had before you started the rebase: | |||||||
| $ git rebase --abort | $ git rebase --abort | ||||||
| ------------------------------------------------- | ------------------------------------------------- | ||||||
|  |  | ||||||
| [[modifying-one-commit]] | [[rewriting-one-commit]] | ||||||
| Modifying a single commit | Rewriting a single commit | ||||||
| ------------------------- | ------------------------- | ||||||
|  |  | ||||||
| We saw in <<fixing-a-mistake-by-editing-history>> that you can replace the | We saw in <<fixing-a-mistake-by-rewriting-history>> that you can replace the | ||||||
| most recent commit using | most recent commit using | ||||||
|  |  | ||||||
| ------------------------------------------------- | ------------------------------------------------- | ||||||
| @ -2440,8 +2491,10 @@ $ git commit --amend | |||||||
| which will replace the old commit by a new commit incorporating your | which will replace the old commit by a new commit incorporating your | ||||||
| changes, giving you a chance to edit the old commit message first. | 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 | You can also use a combination of this and gitlink:git-rebase[1] to | ||||||
| commits further back in your history.  First, tag the problematic commit with | replace a commit further back in your history and recreate the | ||||||
|  | intervening changes on top of it.  First, tag the problematic commit | ||||||
|  | with | ||||||
|  |  | ||||||
| ------------------------------------------------- | ------------------------------------------------- | ||||||
| $ git tag bad mywork~5 | $ git tag bad mywork~5 | ||||||
| @ -3172,6 +3225,127 @@ confusing and scary messages, but it won't actually do anything bad. In | |||||||
| contrast, running "git prune" while somebody is actively changing the | contrast, running "git prune" while somebody is actively changing the | ||||||
| repository is a *BAD* idea). | repository is a *BAD* idea). | ||||||
|  |  | ||||||
|  | [[recovering-from-repository-corruption]] | ||||||
|  | Recovering from repository corruption | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | By design, git treats data trusted to it with caution.  However, even in | ||||||
|  | the absence of bugs in git itself, it is still possible that hardware or | ||||||
|  | operating system errors could corrupt data. | ||||||
|  |  | ||||||
|  | The first defense against such problems is backups.  You can back up a | ||||||
|  | git directory using clone, or just using cp, tar, or any other backup | ||||||
|  | mechanism. | ||||||
|  |  | ||||||
|  | As a last resort, you can search for the corrupted objects and attempt | ||||||
|  | to replace them by hand.  Back up your repository before attempting this | ||||||
|  | in case you corrupt things even more in the process. | ||||||
|  |  | ||||||
|  | We'll assume that the problem is a single missing or corrupted blob, | ||||||
|  | which is sometimes a solveable problem.  (Recovering missing trees and | ||||||
|  | especially commits is *much* harder). | ||||||
|  |  | ||||||
|  | Before starting, verify that there is corruption, and figure out where | ||||||
|  | it is with gitlink:git-fsck[1]; this may be time-consuming. | ||||||
|  |  | ||||||
|  | Assume the output looks like this: | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git-fsck --full | ||||||
|  | broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8 | ||||||
|  |               to    blob 4b9458b3786228369c63936db65827de3cc06200 | ||||||
|  | missing blob 4b9458b3786228369c63936db65827de3cc06200 | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | (Typically there will be some "dangling object" messages too, but they | ||||||
|  | aren't interesting.) | ||||||
|  |  | ||||||
|  | Now you know that blob 4b9458b3 is missing, and that the tree 2d9263c6 | ||||||
|  | points to it.  If you could find just one copy of that missing blob | ||||||
|  | object, possibly in some other repository, you could move it into | ||||||
|  | .git/objects/4b/9458b3... and be done.  Suppose you can't.  You can | ||||||
|  | still examine the tree that pointed to it with gitlink:git-ls-tree[1], | ||||||
|  | which might output something like: | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8 | ||||||
|  | 100644 blob 8d14531846b95bfa3564b58ccfb7913a034323b8	.gitignore | ||||||
|  | 100644 blob ebf9bf84da0aab5ed944264a5db2a65fe3a3e883	.mailmap | ||||||
|  | 100644 blob ca442d313d86dc67e0a2e5d584b465bd382cbf5c	COPYING | ||||||
|  | ... | ||||||
|  | 100644 blob 4b9458b3786228369c63936db65827de3cc06200	myfile | ||||||
|  | ... | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | So now you know that the missing blob was the data for a file named | ||||||
|  | "myfile".  And chances are you can also identify the directory--let's | ||||||
|  | say it's in "somedirectory".  If you're lucky the missing copy might be | ||||||
|  | the same as the copy you have checked out in your working tree at | ||||||
|  | "somedirectory/myfile"; you can test whether that's right with | ||||||
|  | gitlink:git-hash-object[1]: | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git hash-object -w somedirectory/myfile | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | which will create and store a blob object with the contents of | ||||||
|  | somedirectory/myfile, and output the sha1 of that object.  if you're | ||||||
|  | extremely lucky it might be 4b9458b3786228369c63936db65827de3cc06200, in | ||||||
|  | which case you've guessed right, and the corruption is fixed! | ||||||
|  |  | ||||||
|  | Otherwise, you need more information.  How do you tell which version of | ||||||
|  | the file has been lost? | ||||||
|  |  | ||||||
|  | The easiest way to do this is with: | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git log --raw --all --full-history -- somedirectory/myfile | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | Because you're asking for raw output, you'll now get something like | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | commit abc | ||||||
|  | Author: | ||||||
|  | Date: | ||||||
|  | ... | ||||||
|  | :100644 100644 4b9458b... newsha... M somedirectory/myfile | ||||||
|  |  | ||||||
|  |  | ||||||
|  | commit xyz | ||||||
|  | Author: | ||||||
|  | Date: | ||||||
|  |  | ||||||
|  | ... | ||||||
|  | :100644 100644 oldsha... 4b9458b... M somedirectory/myfile | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | This tells you that the immediately preceding version of the file was | ||||||
|  | "newsha", and that the immediately following version was "oldsha". | ||||||
|  | You also know the commit messages that went with the change from oldsha | ||||||
|  | to 4b9458b and with the change from 4b9458b to newsha. | ||||||
|  |  | ||||||
|  | If you've been committing small enough changes, you may now have a good | ||||||
|  | shot at reconstructing the contents of the in-between state 4b9458b. | ||||||
|  |  | ||||||
|  | If you can do that, you can now recreate the missing object with | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git hash-object -w <recreated-file> | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | and your repository is good again! | ||||||
|  |  | ||||||
|  | (Btw, you could have ignored the fsck, and started with doing a | ||||||
|  |  | ||||||
|  | ------------------------------------------------ | ||||||
|  | $ git log --raw --all | ||||||
|  | ------------------------------------------------ | ||||||
|  |  | ||||||
|  | and just looked for the sha of the missing object (4b9458b..) in that | ||||||
|  | whole thing. It's up to you - git does *have* a lot of information, it is | ||||||
|  | just missing one particular blob version. | ||||||
|  |  | ||||||
| [[the-index]] | [[the-index]] | ||||||
| The index | The index | ||||||
| ----------- | ----------- | ||||||
| @ -4382,4 +4556,7 @@ Write a chapter on using plumbing and writing scripts. | |||||||
|  |  | ||||||
| Alternates, clone -reference, etc. | Alternates, clone -reference, etc. | ||||||
|  |  | ||||||
| git unpack-objects -r for recovery | More on recovery from repository corruption.  See: | ||||||
|  | 	http://marc.theaimsgroup.com/?l=git&m=117263864820799&w=2 | ||||||
|  | 	http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2 | ||||||
|  | 	http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2 | ||||||
|  | |||||||
| @ -175,7 +175,7 @@ detach_warn= | |||||||
| describe_detached_head () { | describe_detached_head () { | ||||||
| 	test -n "$quiet" || { | 	test -n "$quiet" || { | ||||||
| 		printf >&2 "$1 " | 		printf >&2 "$1 " | ||||||
| 		GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" | 		GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" -- | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Junio C Hamano
					Junio C Hamano