From ce3650e3d33c0f50037aebb186b18f3e811bb6f2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 26 Nov 2007 04:20:11 +0000 Subject: [PATCH] Autogenerated HTML docs for v1.5.3.6-959-g1ab5 --- user-manual.html | 139 +++++++++++++++++++++++------ user-manual.txt | 225 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 313 insertions(+), 51 deletions(-) diff --git a/user-manual.html b/user-manual.html index 7a887a16c..7478ff325 100644 --- a/user-manual.html +++ b/user-manual.html @@ -1,4 +1,4 @@ -Git User's Manual (for version 1.5.3 or newer)

Git User's Manual (for version 1.5.3 or newer)


Table of Contents

Preface
1. Repositories and Branches
How to get a git repository
How to check out a different version of a project
Understanding History: Commits
Understanding history: commits, parents, and reachability
Understanding history: History diagrams
Understanding history: What is a branch?
Manipulating branches
Examining an old version without creating a new branch
Examining branches from a remote repository
Naming branches, tags, and other references
Updating a repository with git fetch
Fetching branches from other repositories
2. Exploring git history
How to use bisect to find a regression
Naming commits
Creating tags
Browsing revisions
Generating diffs
Viewing old file versions
Examples
Counting the number of commits on a branch
Check whether two branches point at the same history
Find first tagged version including a given fix
Showing commits unique to a given branch
Creating a changelog and tarball for a software release
Finding commits referencing a file with given content
3. Developing with git
Telling git your name
Creating a new repository
How to make a commit
Creating good commit messages
Ignoring files
How to merge
Resolving a merge
Getting conflict-resolution help during a merge
Undoing a merge
Fast-forward merges
Fixing mistakes
Fixing a mistake with a new commit
Fixing a mistake by editing history
Checking out an old version of a file
Temporarily setting aside work in progress
Ensuring good performance
Ensuring reliability
Checking the repository for corruption
Recovering lost changes
4. Sharing development with others
Getting updates with git pull
Submitting patches to a project
Importing patches to a project
Public git repositories
Setting up a public repository
Exporting a git repository via the git protocol
Exporting a git repository via http
Pushing changes to a public repository
Setting up a shared repository
Allowing web browsing of a repository
Examples
Maintaining topic branches for a Linux subsystem maintainer
5. Rewriting history and maintaining patch series
Creating the perfect patch series
Keeping a patch series up to date using git-rebase
Modifying a single commit
Reordering or selecting from a patch series
Other tools
Problems with rewriting history
Why bisecting merge commits can be harder than bisecting linear history
6. Advanced branch management
Fetching individual branches
git fetch and fast-forwards
Forcing git fetch to do non-fast-forward updates
Configuring remote branches
7. Git concepts
The Object Database
Commit Object
Tree Object
Blob Object
Trust
Tag Object
How git stores objects efficiently: pack files
Dangling objects
The index
8. Submodules
Pitfalls with submodules
9. Low-level git operations
Object access and manipulation
The Workflow
working directory -> index
index -> object database
object database -> index
index -> working directory
Tying it all together
Examining the data
Merging multiple trees
Merging multiple trees, continued
10. Hacking git
Object storage format
A birds-eye view of Git's source code
11. GIT Glossary
A. Git Quick Reference
Creating a new repository
Managing branches
Exploring history
Making changes
Merging
Sharing your changes
Repository maintenance
B. Notes and todo list for this manual

Preface

Git is a fast distributed revision control system.

This manual is designed to be readable by someone with basic UNIX +Git User's Manual (for version 1.5.3 or newer)

Git User's Manual (for version 1.5.3 or newer)


Table of Contents

Preface
1. Repositories and Branches
How to get a git repository
How to check out a different version of a project
Understanding History: Commits
Understanding history: commits, parents, and reachability
Understanding history: History diagrams
Understanding history: What is a branch?
Manipulating branches
Examining an old version without creating a new branch
Examining branches from a remote repository
Naming branches, tags, and other references
Updating a repository with git fetch
Fetching branches from other repositories
2. Exploring git history
How to use bisect to find a regression
Naming commits
Creating tags
Browsing revisions
Generating diffs
Viewing old file versions
Examples
Counting the number of commits on a branch
Check whether two branches point at the same history
Find first tagged version including a given fix
Showing commits unique to a given branch
Creating a changelog and tarball for a software release
Finding commits referencing a file with given content
3. Developing with git
Telling git your name
Creating a new repository
How to make a commit
Creating good commit messages
Ignoring files
How to merge
Resolving a merge
Getting conflict-resolution help during a merge
Undoing a merge
Fast-forward merges
Fixing mistakes
Fixing a mistake with a new commit
Fixing a mistake by rewriting history
Checking out an old version of a file
Temporarily setting aside work in progress
Ensuring good performance
Ensuring reliability
Checking the repository for corruption
Recovering lost changes
4. Sharing development with others
Getting updates with git pull
Submitting patches to a project
Importing patches to a project
Public git repositories
Setting up a public repository
Exporting a git repository via the git protocol
Exporting a git repository via http
Pushing changes to a public repository
What to do when a push fails
Setting up a shared repository
Allowing web browsing of a repository
Examples
Maintaining topic branches for a Linux subsystem maintainer
5. Rewriting history and maintaining patch series
Creating the perfect patch series
Keeping a patch series up to date using git-rebase
Rewriting a single commit
Reordering or selecting from a patch series
Other tools
Problems with rewriting history
Why bisecting merge commits can be harder than bisecting linear history
6. Advanced branch management
Fetching individual branches
git fetch and fast-forwards
Forcing git fetch to do non-fast-forward updates
Configuring remote branches
7. Git concepts
The Object Database
Commit Object
Tree Object
Blob Object
Trust
Tag Object
How git stores objects efficiently: pack files
Dangling objects
Recovering from repository corruption
The index
8. Submodules
Pitfalls with submodules
9. Low-level git operations
Object access and manipulation
The Workflow
working directory -> index
index -> object database
object database -> index
index -> working directory
Tying it all together
Examining the data
Merging multiple trees
Merging multiple trees, continued
10. Hacking git
Object storage format
A birds-eye view of Git's source code
11. GIT Glossary
A. Git Quick Reference
Creating a new repository
Managing branches
Exploring history
Making changes
Merging
Sharing your changes
Repository maintenance
B. Notes and todo list for this manual

Preface

Git is a fast distributed revision control system.

This manual is designed to be readable by someone with basic UNIX command-line skills, but no previous knowledge of git.

Chapter 1, Repositories and Branches and Chapter 2, Exploring git history explain how to fetch and study a project using git—read these chapters to learn how to build and test a particular version of a software project, search for @@ -13,15 +13,19 @@ project in mind, here are some interesting examples:

The clone command creates a new directory named after the project ("git" +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, -together with a special top-level directory named ".git", which -contains all the information about the history of the project.

How to check out a different version of a project

Git is best thought of as a tool for storing the history of a collection +called the working tree, together with a special +top-level directory named ".git", which contains all the information +about the history of the project.

How to check out a different version of a project

Git is best thought of as a tool for storing the history of a collection of files. It stores the history as a compressed collection of interrelated snapshots of the project's contents. In git each such -version is called a commit.

A single git repository may contain multiple branches. It keeps track -of them by keeping a list of heads which reference the +version is called a commit.

Those snapshots aren't necessarily all arranged in a single line from +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 heads which reference the latest commit on each branch; the git-branch(1) command shows you the list of branch heads:

$ git branch
* master

A freshly cloned repository contains a single branch head, by default @@ -387,7 +391,7 @@ file such that it contained the given content either before or after the commit. You can find out with this:

$  git log --raw --abbrev=40 --pretty=oneline |
        grep -B 1 `git hash-object filename`

Figuring out why this works is left as an exercise to the (advanced) student. The git-log(1), git-diff-tree(1), and -git-hash-object(1) man pages may prove helpful.

Chapter 3. Developing with git

Telling git your name

Before creating any commits, you should introduce yourself to git. The easiest way to do so is to make sure the following lines appear in a file named .gitconfig in your home directory:

[user]
        name = Your Name Comes Here
@@ -568,14 +572,14 @@ commit; for example, to revert the most recent commit:

$ git revert HEAD^

In this case git will attempt to undo the old change while leaving intact any changes made since then. If more recent changes overlap with the changes to be reverted, then you will be asked to fix -conflicts manually, just as in the case of resolving a merge.

Fixing a mistake by editing history

If the problematic commit is the most recent commit, and you have not +conflicts manually, just as in the case of resolving a merge.

Fixing a mistake by rewriting history

If the problematic commit is the most recent commit, and you have not yet made that commit public, then you may just destroy it using git-reset.

Alternatively, you can edit the working directory and update the index to fix your mistake, just as if you were going to create a new commit, then run

$ 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.

Again, you should never do this to a commit that may already have been merged into another branch; use git-revert(1) instead in -that case.

It is also possible to edit commits further back in the history, but +that case.

It is also possible to replace commits further back in the history, but this is an advanced topic to be left for another chapter.

Checking out an old version of a file

In the process of undoing a previous bad change, you may find it useful to check out an older version of a particular file using @@ -613,7 +617,10 @@ recovering lost work—see you wish, you can remove them with git-prune(1) or the —prune option to git-gc(1):

$ git gc --prune

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 -other git operations are in progress in the same repository.

Recovering lost changes

Reflogs

Say you modify a branch with git-reset(1) —hard, and then +other git operations are in progress in the same repository.

If 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 +the section called “Recovering from repository corruption” for a detailed discussion.

Recovering lost changes

Reflogs

Say you modify a branch with git-reset(1) —hard, and then realize that the branch was the only reference you had to that point in history.

Fortunately, git also keeps a log, called a "reflog", of all the previous values of each branch. So in this case you can still find the @@ -649,7 +656,7 @@ you get exactly the history reachable from that commit that is lost. "tip of the line" as being dangling, but there might be a whole deep and complex commit history that was dropped.)

If you decide you want the history back, you can always create a new reference pointing to it, for example, a new branch:

$ git branch recovered-branch 7281251ddd

Other types of dangling objects (blobs and trees) are also possible, and -dangling objects can arise in other situations.

Chapter 4. Sharing development with others

Getting updates with git pull

After you clone a repository and make a few changes of your own, you may wish to check the original repository for updates and merge them into your own work.

We have already seen how to keep remote tracking branches up to date with git-fetch(1), and how to merge two branches. So you can merge in changes from the @@ -744,11 +751,9 @@ maintainers to fetch your latest changes, but they do not allow write access, which you will need to update the public repository with the latest changes created in your private repository.

The simplest way to do this is using git-push(1) and ssh; to update the remote branch named "master" with the latest state of your -branch named "master", run

$ git push ssh://yourserver.com/~you/proj.git master:master

or just

$ git push ssh://yourserver.com/~you/proj.git master

As with git-fetch, git-push will complain if this does not result in -a fast forward. Normally this is a sign of -something wrong. However, if you are sure you know what you're -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 +branch named "master", run

$ git push ssh://yourserver.com/~you/proj.git master:master

or just

$ git push ssh://yourserver.com/~you/proj.git master

As with git-fetch, git-push will complain if this does not result in a +fast forward; see the following section for details on +handling this case.

Note that the target of a "push" is normally a bare repository. You can also push to a repository that has a checked-out working tree, but the working tree will not be updated by the push. This may lead to unexpected results if @@ -758,7 +763,31 @@ save typing; so, for example, after

$ cat >         url = ssh://yourserver.com/~you/proj.git
EOF

you should be able to perform the above push with just

$ git push public-repo master

See the explanations of the remote.<name>.url, branch.<name>.remote, and remote.<name>.push options in git-config(1) for -details.

Setting up a shared repository

Another way to collaborate is by using a model similar to that +details.

What to do when a push fails

If a push would not result in a 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:

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 the section called “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 +next section and +git for CVS users for more.

Setting up a shared repository

Another way to collaborate is by using a model similar to that commonly used in CVS, where several developers with special rights all push to and pull from a single shared repository. See git for CVS users for instructions on how to @@ -940,7 +969,7 @@ do
                ;;
        esac
        git log origin/master..$branch | git shortlog
-done

Chapter 5. Rewriting history and maintaining patch series

Normally commits are only added to a project, never taken away or +done

Chapter 5. Rewriting history and maintaining patch series

Normally commits are only added to a project, never taken away or replaced. Git is designed with this assumption, and violating it will cause git's merge machinery (for example) to do the wrong thing.

However, there is a situation in which it can be useful to violate this assumption.

Creating the perfect patch series

Suppose you are a contributor to a large project, and you want to add a @@ -989,10 +1018,12 @@ patches to the new mywork. The result will look like:

$ git rebase --continue

and git will continue applying the rest of the patches.

At any point you may use the —abort option to abort this process and -return mywork to the state it had before you started the rebase:

$ git rebase --abort

Modifying a single commit

We saw in the section called “Fixing a mistake by editing history” that you can replace the +return mywork to the state it had before you started the rebase:

$ git rebase --abort

Rewriting a single commit

We saw in the section called “Fixing a mistake by rewriting history” 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 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 that commit, edit it, and rebase the rest of the series +changes, giving you a chance to edit the old commit message first.

You can also use a combination of this and git-rebase(1) to +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

(Either gitk or git-log may be useful for finding the commit.)

Then check out that commit, edit it, and rebase the rest of the series on top of it (note that we could check out the commit on a temporary branch, but instead we're using a detached head):

$ git checkout bad
$ # make changes here and update the index
@@ -1116,7 +1147,7 @@ $ git fetch example

You can also add a "+" to force the update ea throwing away commits on mybranch.

Also note that all of the above configuration can be performed by directly editing the file .git/config instead of using git-config(1).

See git-config(1) for more details on the configuration -options mentioned above.

Chapter 7. Git concepts

Git is built on a small number of simple but powerful ideas. While it +options mentioned above.

Chapter 7. Git concepts

Git is built on a small number of simple but powerful ideas. While it is possible to get things done without understanding them, you will find git much more intuitive if you do.

We start with the most important, the object database and the index.

The Object Database

We already saw in the section called “Understanding History: Commits” that all commits are stored under a 40-digit "object name". In fact, all the information needed to @@ -1330,7 +1361,58 @@ on what it found, git-fsck itself is never "dangerous" to run. Running it while somebody is actually changing the repository can cause 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).

The index

The index is a binary file (generally kept in .git/index) containing a +repository is a BAD idea).

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 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 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 +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 is a binary file (generally kept in .git/index) containing a sorted list of path names, each with permissions and the SHA1 of a blob object; git-ls-files(1) can show you the contents of the index:

$ git ls-files --stage
100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0       .gitignore
@@ -1367,7 +1449,7 @@ column in the git-ls-files(1) outp number, and will take on values other than 0 for files with merge conflicts.

The index is thus a sort of temporary staging area, which is filled with a tree which you are in the process of working on.

If you blow the index away entirely, you generally haven't lost any -information as long as you have the name of the tree that it described.

Chapter 8. Submodules

Table of Contents

Pitfalls with submodules

Large projects are often composed of smaller, self-contained modules. For +information as long as you have the name of the tree that it described.

Chapter 8. Submodules

Table of Contents

Pitfalls with submodules

Large projects are often composed of smaller, self-contained modules. For example, an embedded Linux distribution's source tree would include every piece of software in the distribution with some local modifications; a movie player might need to build against a specific, known-working version of a @@ -1461,7 +1543,7 @@ index d266b98..261dfac 160000
$ git add a
$ git commit -m "Updated submodule a."
$ git push

You have to run git submodule update after git pull if you want to update -submodules, too.

Pitfalls with submodules

Always publish the submodule change before publishing the change to the +submodules, too.

Pitfalls with submodules

Always publish the submodule change before publishing the change to the superproject that references it. If you forget to publish the submodule change, others won't be able to clone the repository:

$ cd ~/git/super/a
$ echo i added another line to this file >> a.txt
@@ -2386,4 +2468,7 @@ temporary branch creation?

Add more good examples. Entire sections of jus might be a good idea; maybe make an "advanced examples" section a standard end-of-chapter section?

Include cross-references to the glossary, where appropriate.

Document shallow clones? See draft 1.5.0 release notes for some documentation.

Add a section on working with other version control systems, including -CVS, Subversion, and just imports of series of release tarballs.

More details on gitweb?

Write a chapter on using plumbing and writing scripts.

Alternates, clone -reference, etc.

git unpack-objects -r for recovery

+CVS, Subversion, and just imports of series of release tarballs.

More details on gitweb?

Write a chapter on using plumbing and writing scripts.

Alternates, clone -reference, etc.

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

diff --git a/user-manual.txt b/user-manual.txt index 3661879f1..0aaed10c7 100644 --- a/user-manual.txt +++ b/user-manual.txt @@ -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 will only need to clone once. -The clone command creates a new directory named after the project -("git" or "linux-2.6" in the examples above). After you cd into this +The clone command creates a new directory named after the project ("git" +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, -together with a special top-level directory named ".git", which -contains all the information about the history of the project. +called the <>, together with a special +top-level directory named ".git", which contains all the information +about the history of the project. [[how-to-check-out]] 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 version is called a <>. -A single git repository may contain multiple branches. It keeps track -of them by keeping a list of <> which reference the +Those snapshots aren't necessarily all arranged in a single line from +oldest to newest; instead, work may simultaneously proceed along +parallel lines of development, called >, which may +merge and diverge. + +A single git repository can track development on multiple branches. It +does this by keeping a list of <> which reference the latest commit on each branch; the gitlink:git-branch[1] command shows 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 <>. -[[fixing-a-mistake-by-editing-history]] -Fixing a mistake by editing history +[[fixing-a-mistake-by-rewriting-history]] +Fixing a mistake by rewriting history ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 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 <>. @@ -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 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 +<> for a detailed discussion. + [[recovering-lost-changes]] Recovering lost changes ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1923,15 +1934,9 @@ or just $ git push ssh://yourserver.com/~you/proj.git master ------------------------------------------------- -As with git-fetch, git-push will complain if this does not result in -a <>. Normally this is a sign of -something wrong. However, if you are sure you know what you're -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 -------------------------------------------------- +As with git-fetch, git-push will complain if this does not result in a +<>; see the following section for details on +handling this case. Note that the target of a "push" is normally a <> repository. You can also push to a @@ -1959,6 +1964,52 @@ See the explanations of the remote..url, branch..remote, and remote..push options in gitlink:git-config[1] for details. +[[forcing-push]] +What to do when a push fails +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If a push would not result in a <> 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 <>), or + - use `git rebase` to rebase any already-published commits (as + in <>). + +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 <>.) + +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 +<> and +link:cvs-migration.html[git for CVS users] for more. + [[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 ------------------------------------------------- -[[modifying-one-commit]] -Modifying a single commit +[[rewriting-one-commit]] +Rewriting a single commit ------------------------- -We saw in <> that you can replace the +We saw in <> that you can replace the most recent commit using ------------------------------------------------- @@ -2440,8 +2491,10 @@ $ 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 +You can also use a combination of this and gitlink:git-rebase[1] to +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 @@ -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 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 +------------------------------------------------ + +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 ----------- @@ -4382,4 +4556,7 @@ Write a chapter on using plumbing and writing scripts. 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 -- 2.26.2