diff options
Diffstat (limited to 'assets/info/git.info')
| -rw-r--r-- | assets/info/git.info | 5681 |
1 files changed, 5681 insertions, 0 deletions
diff --git a/assets/info/git.info b/assets/info/git.info new file mode 100644 index 00000000..6c91b18a --- /dev/null +++ b/assets/info/git.info @@ -0,0 +1,5681 @@ +This is git.info, produced by makeinfo version 6.5 from +user-manual.texi. + +INFO-DIR-SECTION Development +START-INFO-DIR-ENTRY +* Git: (git). A fast distributed revision control system +END-INFO-DIR-ENTRY + + +File: git.info, Node: Top, Next: idm4, Up: (dir) + +Git User Manual +*************** + +* Menu: + +* : idm4. +* Repositories and Branches:: +* Exploring Git history:: +* Developing with Git:: +* Sharing development with others:: +* Rewriting history and maintaining patch series:: +* Advanced branch management:: +* Git concepts:: +* Submodules:: +* Low-level Git operations:: +* Hacking Git:: +* Git Glossary:: +* Git Quick Reference:: +* Notes and todo list for this manual:: + +— The Detailed Node Listing — + +Repositories and Branches + +* How to get a Git repository:: +* How to check out a different version of a project:: +* Understanding History; Commits:: +* Manipulating branches:: +* Examining an old version without creating a new branch:: +* Examining branches from a remote repository:: +* Naming branches, tags, and other references: Naming branches; tags; and other references. +* Updating a repository with git fetch:: +* Fetching branches from other repositories:: + +Exploring Git history + +* How to use bisect to find a regression:: +* Naming commits:: +* Creating tags:: +* Browsing revisions:: +* Generating diffs:: +* Viewing old file versions:: +* Examples:: + +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:: +* Undoing a merge:: +* Fast-forward merges:: +* Fixing mistakes:: +* Ensuring good performance:: +* Ensuring reliability:: + +Sharing development with others + +* Getting updates with git pull:: +* Submitting patches to a project:: +* Importing patches to a project:: +* Public Git repositories:: +* How to get a Git repository with minimal history:: +* Examples: Examples <1>. + +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:: +* Using interactive rebases:: +* Other tools:: +* Problems with rewriting history:: +* Why bisecting merge commits can be harder than bisecting linear history:: + +Advanced branch management + +* Fetching individual branches:: +* git fetch and fast-forwards:: +* Forcing git fetch to do non-fast-forward updates:: +* Configuring remote-tracking branches:: + +Git concepts + +* The Object Database:: +* The index:: + +Submodules + +* Pitfalls with submodules:: + +Low-level Git operations + +* Object access and manipulation:: +* The Workflow:: +* Examining the data:: +* Merging multiple trees:: +* Merging multiple trees, continued: Merging multiple trees; continued. + +Hacking Git + +* Object storage format:: +* A birds-eye view of Git’s source code:: + +Git Glossary + +* Git explained:: + +Git Quick Reference + +* Creating a new repository: Creating a new repository <1>. +* Managing branches:: +* Exploring history:: +* Making changes:: +* Merging:: +* Sharing your changes:: +* Repository maintenance:: + +Notes and todo list for this manual + +* Todo list:: + + + +File: git.info, Node: idm4, Next: Repositories and Branches, Prev: Top, Up: Top + +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. + + *note Repositories and Branches:: and *note 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 regressions, and so on. + + People needing to do actual development will also want to read *note +Developing with Git:: and *note Sharing development with others::. + + Further chapters cover more specialized topics. + + Comprehensive reference documentation is available through the man +pages, or git-help(1) (git-help.html) command. For example, for the +command ‘git clone <repo>’, you can either use: + + $ man git-clone + + or: + + $ git help clone + + With the latter, you can use the manual viewer of your choice; see +git-help(1) (git-help.html) for more information. + + See also *note Git Quick Reference:: for a brief overview of Git +commands, without any explanation. + + Finally, see *note Notes and todo list for this manual:: for ways +that you can help make this manual more complete. + + +File: git.info, Node: Repositories and Branches, Next: Exploring Git history, Prev: idm4, Up: Top + +1 Repositories and Branches +*************************** + +* Menu: + +* How to get a Git repository:: +* How to check out a different version of a project:: +* Understanding History; Commits:: +* Manipulating branches:: +* Examining an old version without creating a new branch:: +* Examining branches from a remote repository:: +* Naming branches, tags, and other references: Naming branches; tags; and other references. +* Updating a repository with git fetch:: +* Fetching branches from other repositories:: + + +File: git.info, Node: How to get a Git repository, Next: How to check out a different version of a project, Up: Repositories and Branches + +1.1 How to get a Git repository +=============================== + +It will be useful to have a Git repository to experiment with as you +read this manual. + + The best way to get one is by using the git-clone(1) (git-clone.html) +command to download a copy of an existing repository. If you don’t +already have a project in mind, here are some interesting examples: + + # Git itself (approx. 40MB download): + $ git clone git://git.kernel.org/pub/scm/git/git.git + # the Linux kernel (approx. 640MB download): + $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.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’ in the examples above). After you cd into this +directory, you will see that it contains a copy of the project files, +called the working tree (*note [def_working_tree]::), together with a +special top-level directory named ‘.git’, which contains all the +information about the history of the project. + + +File: git.info, Node: How to check out a different version of a project, Next: Understanding History; Commits, Prev: How to get a Git repository, Up: Repositories and Branches + +1.2 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 (*note [def_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 branches (*note [def_branch]::), +which may merge and diverge. + + A single Git repository can track development on multiple branches. +It does this by keeping a list of heads (*note [def_head]::) which +reference the latest commit on each branch; the git-branch(1) +(git-branch.html) command shows you the list of branch heads: + + $ git branch + * master + + A freshly cloned repository contains a single branch head, by default +named "master", with the working directory initialized to the state of +the project referred to by that branch head. + + Most projects also use tags (*note [def_tag]::). Tags, like heads, +are references into the project’s history, and can be listed using the +git-tag(1) (git-tag.html) command: + + $ git tag -l + v2.6.11 + v2.6.11-tree + v2.6.12 + v2.6.12-rc2 + v2.6.12-rc3 + v2.6.12-rc4 + v2.6.12-rc5 + v2.6.12-rc6 + v2.6.13 + ... + + Tags are expected to always point at the same version of a project, +while heads are expected to advance as development progresses. + + Create a new branch head pointing to one of these versions and check +it out using git-switch(1) (git-switch.html): + + $ git switch -c new v2.6.13 + + The working directory then reflects the contents that the project had +when it was tagged v2.6.13, and git-branch(1) (git-branch.html) shows +two branches, with an asterisk marking the currently checked-out branch: + + $ git branch + master + * new + + If you decide that you’d rather see version 2.6.17, you can modify +the current branch to point at v2.6.17 instead, with + + $ git reset --hard v2.6.17 + + 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. + + +File: git.info, Node: Understanding History; Commits, Next: Manipulating branches, Prev: How to check out a different version of a project, Up: Repositories and Branches + +1.3 Understanding History: Commits +================================== + +Every change in the history of a project is represented by a commit. +The git-show(1) (git-show.html) command shows the most recent commit on +the current branch: + + $ git show + commit 17cf781661e6d38f737f15f53ab552f1e95960d7 + Author: Linus Torvalds <torvalds@ppc970.osdl.org.(none)> + Date: Tue Apr 19 14:11:06 2005 -0700 + + Remove duplicate getenv(DB_ENVIRONMENT) call + + Noted by Tony Luck. + + diff --git a/init-db.c b/init-db.c + index 65898fa..b002dc6 100644 + --- a/init-db.c + +++ b/init-db.c + @@ -7,7 +7,7 @@ + + int main(int argc, char **argv) + { + - char *sha1_dir = getenv(DB_ENVIRONMENT), *path; + + char *sha1_dir, *path; + int len, i; + + if (mkdir(".git", 0755) < 0) { + + 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 "SHA-1 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 *note Git concepts:: 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. + +* Menu: + +* Understanding history; commits, parents, and reachability: Understanding history; commits; parents; and reachability. +* Understanding history; History diagrams:: +* Understanding history; What is a branch?:: + + +File: git.info, Node: Understanding history; commits; parents; and reachability, Next: Understanding history; History diagrams, Up: Understanding History; Commits + +1.3.1 Understanding history: commits, parents, and reachability +--------------------------------------------------------------- + +Every commit (except the very first commit in a project) also has a +parent commit which shows what happened before this commit. Following +the chain of parents will eventually take you back to the beginning of +the project. + + However, the commits do not form a simple list; Git allows lines of +development to diverge and then reconverge, and the point where two +lines of development reconverge is called a "merge". The commit +representing a merge can therefore have more than one parent, with each +parent representing the most recent commit on one of the lines of +development leading to that point. + + The best way to see how this works is using the gitk(1) (gitk.html) +command; running gitk now on a Git repository and looking for merge +commits will help understand how Git organizes history. + + In the following, we say that commit X is "reachable" from commit Y +if commit X is an ancestor of commit Y. Equivalently, you could say that +Y is a descendant of X, or that there is a chain of parents leading from +commit Y to commit X. + + +File: git.info, Node: Understanding history; History diagrams, Next: Understanding history; What is a branch?, Prev: Understanding history; commits; parents; and reachability, Up: Understanding History; Commits + +1.3.2 Understanding history: History diagrams +--------------------------------------------- + +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. + + +File: git.info, Node: Understanding history; What is a branch?, Prev: Understanding history; History diagrams, Up: Understanding History; Commits + +1.3.3 Understanding history: What is a branch? +---------------------------------------------- + +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". + + However, when no confusion will result, we often just use the term +"branch" both for branches and for branch heads. + + +File: git.info, Node: Manipulating branches, Next: Examining an old version without creating a new branch, Prev: Understanding History; Commits, Up: Repositories and Branches + +1.4 Manipulating branches +========================= + +Creating, deleting, and modifying branches is quick and easy; here’s a +summary of the commands: + +‘git branch’ + list all branches. + +‘git branch <branch>’ + create a new branch named ‘<branch>’, referencing the same point in + history as the current branch. + +‘git branch <branch> <start-point>’ + create a new branch named ‘<branch>’, referencing ‘<start-point>’, + which may be specified any way you like, including using a branch + name or a tag name. + +‘git branch -d <branch>’ + delete the branch ‘<branch>’; if the branch is not fully merged in + its upstream branch or contained in the current branch, this + command will fail with a warning. + +‘git branch -D <branch>’ + delete the branch ‘<branch>’ irrespective of its merged status. + +‘git switch <branch>’ + make the current branch ‘<branch>’, updating the working directory + to reflect the version referenced by ‘<branch>’. + +‘git switch -c <new> <start-point>’ + create a new branch ‘<new>’ referencing ‘<start-point>’, and check + it out. + + The special symbol "HEAD" can always be used to refer to the current +branch. In fact, Git uses a file named ‘HEAD’ in the ‘.git’ directory +to remember which branch is current: + + $ cat .git/HEAD + ref: refs/heads/master + + +File: git.info, Node: Examining an old version without creating a new branch, Next: Examining branches from a remote repository, Prev: Manipulating branches, Up: Repositories and Branches + +1.5 Examining an old version without creating a new branch +========================================================== + +The ‘git switch’ command normally expects a branch head, but will also +accept an arbitrary commit when invoked with –detach; for example, you +can check out the commit referenced by a tag: + + $ git switch --detach v2.6.17 + Note: checking out 'v2.6.17'. + + You are in 'detached HEAD' state. You can look around, make experimental + changes and commit them, and you can discard any commits you make in this + state without impacting any branches by performing another switch. + + If you want to create a new branch to retain commits you create, you may + do so (now or later) by using -c with the switch command again. Example: + + git switch -c new_branch_name + + HEAD is now at 427abfa Linux v2.6.17 + + The HEAD then refers to the SHA-1 of the commit instead of to a +branch, and git branch shows that you are no longer on a branch: + + $ cat .git/HEAD + 427abfa28afedffadfca9dd8b067eb6d36bac53f + $ git branch + * (detached from v2.6.17) + master + + In this case we say that the HEAD is "detached". + + This is an easy way to check out a particular version without having +to make up a name for the new branch. You can still create a new branch +(or tag) for this version later if you decide to. + + +File: git.info, Node: Examining branches from a remote repository, Next: Naming branches; tags; and other references, Prev: Examining an old version without creating a new branch, Up: Repositories and Branches + +1.6 Examining branches from a remote repository +=============================================== + +The "master" branch that was created at the time you cloned is a copy of +the HEAD in the repository that you cloned from. That repository may +also have had other branches, though, and your local repository keeps +branches which track each of those remote branches, called +remote-tracking branches, which you can view using the ‘-r’ option to +git-branch(1) (git-branch.html): + + $ git branch -r + origin/HEAD + origin/html + origin/maint + origin/man + origin/master + origin/next + origin/seen + origin/todo + + In this example, "origin" is called a remote repository, or "remote" +for short. The branches of this repository are called "remote branches" +from our point of view. The remote-tracking branches listed above were +created based on the remote branches at clone time and will be updated +by ‘git fetch’ (hence ‘git pull’) and ‘git push’. See *note Updating a +repository with git fetch:: for details. + + You might want to build on one of these remote-tracking branches on a +branch of your own, just as you would for a tag: + + $ git switch -c my-todo-copy origin/todo + + You can also check out ‘origin/todo’ directly to examine it or write +a one-off patch. See detached head (*note Examining an old version +without creating a new branch::). + + Note that the name "origin" is just the name that Git uses by default +to refer to the repository that you cloned from. + + +File: git.info, Node: Naming branches; tags; and other references, Next: Updating a repository with git fetch, Prev: Examining branches from a remote repository, Up: Repositories and Branches + +1.7 Naming branches, tags, and other references +=============================================== + +Branches, remote-tracking branches, and tags are all references to +commits. All references are named with a slash-separated path name +starting with ‘refs’; the names we’ve been using so far are actually +shorthand: + + • The branch ‘test’ is short for ‘refs/heads/test’. + + • The tag ‘v2.6.18’ is short for ‘refs/tags/v2.6.18’. + + • ‘origin/master’ is short for ‘refs/remotes/origin/master’. + + The full name is occasionally useful if, for example, there ever +exists a tag and a branch with the same name. + + (Newly created refs are actually stored in the ‘.git/refs’ directory, +under the path given by their name. However, for efficiency reasons +they may also be packed together in a single file; see git-pack-refs(1) +(git-pack-refs.html)). + + As another useful shortcut, the "HEAD" of a repository can be +referred to just using the name of that repository. So, for example, +"origin" is usually a shortcut for the HEAD branch in the repository +"origin". + + For the complete list of paths which Git checks for references, and +the order it uses to decide which to choose when there are multiple +references with the same shorthand name, see the "SPECIFYING REVISIONS" +section of gitrevisions(7) (gitrevisions.html). + + +File: git.info, Node: Updating a repository with git fetch, Next: Fetching branches from other repositories, Prev: Naming branches; tags; and other references, Up: Repositories and Branches + +1.8 Updating a repository with git fetch +======================================== + +After you clone a repository and commit a few changes of your own, you +may wish to check the original repository for updates. + + The ‘git-fetch’ command, with no arguments, will update all of the +remote-tracking branches to the latest version found in the original +repository. It will not touch any of your own branches—not even the +"master" branch that was created for you on clone. + + +File: git.info, Node: Fetching branches from other repositories, Prev: Updating a repository with git fetch, Up: Repositories and Branches + +1.9 Fetching branches from other repositories +============================================= + +You can also track branches from repositories other than the one you +cloned from, using git-remote(1) (git-remote.html): + + $ git remote add staging git://git.kernel.org/.../gregkh/staging.git + $ git fetch staging + ... + From git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging + * [new branch] master -> staging/master + * [new branch] staging-linus -> staging/staging-linus + * [new branch] staging-next -> staging/staging-next + + New remote-tracking branches will be stored under the shorthand name +that you gave ‘git remote add’, in this case ‘staging’: + + $ git branch -r + origin/HEAD -> origin/master + origin/master + staging/master + staging/staging-linus + staging/staging-next + + If you run ‘git fetch <remote>’ later, the remote-tracking branches +for the named ‘<remote>’ will be updated. + + If you examine the file ‘.git/config’, you will see that Git has +added a new stanza: + + $ cat .git/config + ... + [remote "staging"] + url = git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git + fetch = +refs/heads/*:refs/remotes/staging/* + ... + + This is what causes Git to track the remote’s branches; you may +modify or delete these configuration options by editing ‘.git/config’ +with a text editor. (See the "CONFIGURATION FILE" section of +git-config(1) (git-config.html) for details.) + + +File: git.info, Node: Exploring Git history, Next: Developing with Git, Prev: Repositories and Branches, Up: Top + +2 Exploring Git history +*********************** + +Git is best thought of as a tool for storing the history of a collection +of files. It does this by storing compressed snapshots of the contents +of a file hierarchy, together with "commits" which show the +relationships between these snapshots. + + Git provides extremely flexible and fast tools for exploring the +history of a project. + + We start with one specialized tool that is useful for finding the +commit that introduced a bug into a project. + +* Menu: + +* How to use bisect to find a regression:: +* Naming commits:: +* Creating tags:: +* Browsing revisions:: +* Generating diffs:: +* Viewing old file versions:: +* Examples:: + + +File: git.info, Node: How to use bisect to find a regression, Next: Naming commits, Up: Exploring Git history + +2.1 How to use bisect to find a regression +========================================== + +Suppose version 2.6.18 of your project worked, but the version at +"master" crashes. Sometimes the best way to find the cause of such a +regression is to perform a brute-force search through the project’s +history to find the particular commit that caused the problem. The +git-bisect(1) (git-bisect.html) command can help you do this: + + $ git bisect start + $ git bisect good v2.6.18 + $ git bisect bad master + Bisecting: 3537 revisions left to test after this + [65934a9a028b88e83e2b0f8b36618fe503349f8e] BLOCK: Make USB storage depend on SCSI rather than selecting it [try #6] + + If you run ‘git branch’ at this point, you’ll see that Git has +temporarily moved you in "(no branch)". HEAD is now detached from any +branch and points directly to a commit (with commit id 65934) that is +reachable from "master" but not from v2.6.18. Compile and test it, and +see whether it crashes. Assume it does crash. Then: + + $ git bisect bad + Bisecting: 1769 revisions left to test after this + [7eff82c8b1511017ae605f0c99ac275a7e21b867] i2c-core: Drop useless bitmaskings + + checks out an older version. Continue like this, telling Git at each +stage whether the version it gives you is good or bad, and notice that +the number of revisions left to test is cut approximately in half each +time. + + After about 13 tests (in this case), it will output the commit id of +the guilty commit. You can then examine the commit with git-show(1) +(git-show.html), find out who wrote it, and mail them your bug report +with the commit id. Finally, run + + $ git bisect reset + + to return you to the branch you were on before. + + Note that the version which ‘git bisect’ checks out for you at each +point is just a suggestion, and you’re free to try a different version +if you think it would be a good idea. For example, occasionally you may +land on a commit that broke something unrelated; run + + $ git bisect visualize + + which will run gitk and label the commit it chose with a marker that +says "bisect". Choose a safe-looking commit nearby, note its commit id, +and check it out with: + + $ git reset --hard fb47ddb2db + + then test, run ‘bisect good’ or ‘bisect bad’ as appropriate, and +continue. + + Instead of ‘git bisect visualize’ and then ‘git reset --hard +fb47ddb2db’, you might just want to tell Git that you want to skip the +current commit: + + $ git bisect skip + + In this case, though, Git may not eventually be able to tell the +first bad one between some first skipped commits and a later bad commit. + + There are also ways to automate the bisecting process if you have a +test script that can tell a good from a bad commit. See git-bisect(1) +(git-bisect.html) for more information about this and other ‘git bisect’ +features. + + +File: git.info, Node: Naming commits, Next: Creating tags, Prev: How to use bisect to find a regression, Up: Exploring Git history + +2.2 Naming commits +================== + +We have seen several ways of naming commits already: + + • 40-hexdigit object name + + • branch name: refers to the commit at the head of the given branch + + • tag name: refers to the commit pointed to by the given tag (we’ve + seen branches and tags are special cases of references (*note + Naming branches; tags; and other references::)). + + • HEAD: refers to the head of the current branch + + There are many more; see the "SPECIFYING REVISIONS" section of the +gitrevisions(7) (gitrevisions.html) man page for the complete list of +ways to name revisions. Some examples: + + $ git show fb47ddb2 # the first few characters of the object name + # are usually enough to specify it uniquely + $ git show HEAD^ # the parent of the HEAD commit + $ git show HEAD^^ # the grandparent + $ git show HEAD~4 # the great-great-grandparent + + Recall that merge commits may have more than one parent; by default, +‘^’ and ‘~’ follow the first parent listed in the commit, but you can +also choose: + + $ git show HEAD^1 # show the first parent of HEAD + $ git show HEAD^2 # show the second parent of HEAD + + In addition to HEAD, there are several other special names for +commits: + + Merges (to be discussed later), as well as operations such as ‘git +reset’, which change the currently checked-out commit, generally set +ORIG_HEAD to the value HEAD had before the current operation. + + The ‘git fetch’ operation always stores the head of the last fetched +branch in FETCH_HEAD. For example, if you run ‘git fetch’ without +specifying a local branch as the target of the operation + + $ git fetch git://example.com/proj.git theirbranch + + the fetched commits will still be available from FETCH_HEAD. + + When we discuss merges we’ll also see the special name MERGE_HEAD, +which refers to the other branch that we’re merging in to the current +branch. + + The git-rev-parse(1) (git-rev-parse.html) command is a low-level +command that is occasionally useful for translating some name for a +commit to the object name for that commit: + + $ git rev-parse origin + e05db0fd4f31dde7005f075a84f96b360d05984b + + +File: git.info, Node: Creating tags, Next: Browsing revisions, Prev: Naming commits, Up: Exploring Git history + +2.3 Creating tags +================= + +We can also create a tag to refer to a particular commit; after running + + $ git tag stable-1 1b2e1d63ff + + You can use ‘stable-1’ to refer to the commit 1b2e1d63ff. + + This creates a "lightweight" tag. If you would also like to include +a comment with the tag, and possibly sign it cryptographically, then you +should create a tag object instead; see the git-tag(1) (git-tag.html) +man page for details. + + +File: git.info, Node: Browsing revisions, Next: Generating diffs, Prev: Creating tags, Up: Exploring Git history + +2.4 Browsing revisions +====================== + +The git-log(1) (git-log.html) command can show lists of commits. On its +own, it shows all commits reachable from the parent commit; but you can +also make more specific requests: + + $ git log v2.5.. # commits since (not reachable from) v2.5 + $ git log test..master # commits reachable from master but not test + $ git log master..test # ...reachable from test but not master + $ git log master...test # ...reachable from either test or master, + # but not both + $ git log --since="2 weeks ago" # commits from the last 2 weeks + $ git log Makefile # commits which modify Makefile + $ git log fs/ # ... which modify any file under fs/ + $ git log -S'foo()' # commits which add or remove any file data + # matching the string 'foo()' + + And of course you can combine all of these; the following finds +commits since v2.5 which touch the ‘Makefile’ or any file under ‘fs’: + + $ git log v2.5.. Makefile fs/ + + You can also ask git log to show patches: + + $ git log -p + + See the ‘--pretty’ option in the git-log(1) (git-log.html) man page +for more display options. + + Note that git log starts with the most recent commit and works +backwards through the parents; however, since Git history can contain +multiple independent lines of development, the particular order that +commits are listed in may be somewhat arbitrary. + + +File: git.info, Node: Generating diffs, Next: Viewing old file versions, Prev: Browsing revisions, Up: Exploring Git history + +2.5 Generating diffs +==================== + +You can generate diffs between any two versions using git-diff(1) +(git-diff.html): + + $ git diff master..test + + That will produce the diff between the tips of the two branches. If +you’d prefer to find the diff from their common ancestor to test, you +can use three dots instead of two: + + $ git diff master...test + + Sometimes what you want instead is a set of patches; for this you can +use git-format-patch(1) (git-format-patch.html): + + $ git format-patch master..test + + will generate a file with a patch for each commit reachable from test +but not from master. + + +File: git.info, Node: Viewing old file versions, Next: Examples, Prev: Generating diffs, Up: Exploring Git history + +2.6 Viewing old file versions +============================= + +You can always view an old version of a file by just checking out the +correct revision first. But sometimes it is more convenient to be able +to view an old version of a single file without checking anything out; +this command does that: + + $ git show v2.5:fs/locks.c + + Before the colon may be anything that names a commit, and after it +may be any path to a file tracked by Git. + + +File: git.info, Node: Examples, Prev: Viewing old file versions, Up: Exploring Git history + +2.7 Examples +============ + +* Menu: + +* 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:: + + +File: git.info, Node: Counting the number of commits on a branch, Next: Check whether two branches point at the same history, Up: Examples + +2.7.1 Counting the number of commits on a branch +------------------------------------------------ + +Suppose you want to know how many commits you’ve made on ‘mybranch’ +since it diverged from ‘origin’: + + $ git log --pretty=oneline origin..mybranch | wc -l + + Alternatively, you may often see this sort of thing done with the +lower-level command git-rev-list(1) (git-rev-list.html), which just +lists the SHA-1’s of all the given commits: + + $ git rev-list origin..mybranch | wc -l + + +File: git.info, Node: Check whether two branches point at the same history, Next: Find first tagged version including a given fix, Prev: Counting the number of commits on a branch, Up: Examples + +2.7.2 Check whether two branches point at the same history +---------------------------------------------------------- + +Suppose you want to check whether two branches point at the same point +in history. + + $ git diff origin..master + + will tell you whether the contents of the project are the same at the +two branches; in theory, however, it’s possible that the same project +contents could have been arrived at by two different historical routes. +You could compare the object names: + + $ git rev-list origin + e05db0fd4f31dde7005f075a84f96b360d05984b + $ git rev-list master + e05db0fd4f31dde7005f075a84f96b360d05984b + + Or you could recall that the ‘...’ operator selects all commits +reachable from either one reference or the other but not both; so + + $ git log origin...master + + will return no commits when the two branches are equal. + + +File: git.info, Node: Find first tagged version including a given fix, Next: Showing commits unique to a given branch, Prev: Check whether two branches point at the same history, Up: Examples + +2.7.3 Find first tagged version including a given fix +----------------------------------------------------- + +Suppose you know that the commit e05db0fd fixed a certain problem. +You’d like to find the earliest tagged release that contains that fix. + + Of course, there may be more than one answer—if the history branched +after commit e05db0fd, then there could be multiple "earliest" tagged +releases. + + You could just visually inspect the commits since e05db0fd: + + $ gitk e05db0fd.. + + or you can use git-name-rev(1) (git-name-rev.html), which will give +the commit a name based on any tag it finds pointing to one of the +commit’s descendants: + + $ git name-rev --tags e05db0fd + e05db0fd tags/v1.5.0-rc1^0~23 + + The git-describe(1) (git-describe.html) command does the opposite, +naming the revision using a tag on which the given commit is based: + + $ git describe e05db0fd + v1.5.0-rc0-260-ge05db0f + + but that may sometimes help you guess which tags might come after the +given commit. + + If you just want to verify whether a given tagged version contains a +given commit, you could use git-merge-base(1) (git-merge-base.html): + + $ git merge-base e05db0fd v1.5.0-rc1 + e05db0fd4f31dde7005f075a84f96b360d05984b + + The merge-base command finds a common ancestor of the given commits, +and always returns one or the other in the case where one is a +descendant of the other; so the above output shows that e05db0fd +actually is an ancestor of v1.5.0-rc1. + + Alternatively, note that + + $ git log v1.5.0-rc1..e05db0fd + + will produce empty output if and only if v1.5.0-rc1 includes +e05db0fd, because it outputs only commits that are not reachable from +v1.5.0-rc1. + + As yet another alternative, the git-show-branch(1) +(git-show-branch.html) command lists the commits reachable from its +arguments with a display on the left-hand side that indicates which +arguments that commit is reachable from. So, if you run something like + + $ git show-branch e05db0fd v1.5.0-rc0 v1.5.0-rc1 v1.5.0-rc2 + ! [e05db0fd] Fix warnings in sha1_file.c - use C99 printf format if + available + ! [v1.5.0-rc0] GIT v1.5.0 preview + ! [v1.5.0-rc1] GIT v1.5.0-rc1 + ! [v1.5.0-rc2] GIT v1.5.0-rc2 + ... + + then a line like + + + ++ [e05db0fd] Fix warnings in sha1_file.c - use C99 printf format if + available + + shows that e05db0fd is reachable from itself, from v1.5.0-rc1, and +from v1.5.0-rc2, and not from v1.5.0-rc0. + + +File: git.info, Node: Showing commits unique to a given branch, Next: Creating a changelog and tarball for a software release, Prev: Find first tagged version including a given fix, Up: Examples + +2.7.4 Showing commits unique to a given branch +---------------------------------------------- + +Suppose you would like to see all the commits reachable from the branch +head named ‘master’ but not from any other head in your repository. + + We can list all the heads in this repository with git-show-ref(1) +(git-show-ref.html): + + $ git show-ref --heads + bf62196b5e363d73353a9dcf094c59595f3153b7 refs/heads/core-tutorial + db768d5504c1bb46f63ee9d6e1772bd047e05bf9 refs/heads/maint + a07157ac624b2524a059a3414e99f6f44bebc1e7 refs/heads/master + 24dbc180ea14dc1aebe09f14c8ecf32010690627 refs/heads/tutorial-2 + 1e87486ae06626c2f31eaa63d26fc0fd646c8af2 refs/heads/tutorial-fixes + + We can get just the branch-head names, and remove ‘master’, with the +help of the standard utilities cut and grep: + + $ git show-ref --heads | cut -d' ' -f2 | grep -v '^refs/heads/master' + refs/heads/core-tutorial + refs/heads/maint + refs/heads/tutorial-2 + refs/heads/tutorial-fixes + + And then we can ask to see all the commits reachable from master but +not from these other heads: + + $ gitk master --not $( git show-ref --heads | cut -d' ' -f2 | + grep -v '^refs/heads/master' ) + + Obviously, endless variations are possible; for example, to see all +commits reachable from some head but not from any tag in the repository: + + $ gitk $( git show-ref --heads ) --not $( git show-ref --tags ) + + (See gitrevisions(7) (gitrevisions.html) for explanations of +commit-selecting syntax such as ‘--not’.) + + +File: git.info, Node: Creating a changelog and tarball for a software release, Next: Finding commits referencing a file with given content, Prev: Showing commits unique to a given branch, Up: Examples + +2.7.5 Creating a changelog and tarball for a software release +------------------------------------------------------------- + +The git-archive(1) (git-archive.html) command can create a tar or zip +archive from any version of a project; for example: + + $ git archive -o latest.tar.gz --prefix=project/ HEAD + + will use HEAD to produce a gzipped tar archive in which each filename +is preceded by ‘project/’. The output file format is inferred from the +output file extension if possible, see git-archive(1) (git-archive.html) +for details. + + Versions of Git older than 1.7.7 don’t know about the ‘tar.gz’ +format, you’ll need to use gzip explicitly: + + $ git archive --format=tar --prefix=project/ HEAD | gzip >latest.tar.gz + + If you’re releasing a new version of a software project, you may want +to simultaneously make a changelog to include in the release +announcement. + + Linus Torvalds, for example, makes new kernel releases by tagging +them, then running: + + $ release-script 2.6.12 2.6.13-rc6 2.6.13-rc7 + + where release-script is a shell script that looks like: + + #!/bin/sh + stable="$1" + last="$2" + new="$3" + echo "# git tag v$new" + echo "git archive --prefix=linux-$new/ v$new | gzip -9 > ../linux-$new.tar.gz" + echo "git diff v$stable v$new | gzip -9 > ../patch-$new.gz" + echo "git log --no-merges v$new ^v$last > ../ChangeLog-$new" + echo "git shortlog --no-merges v$new ^v$last > ../ShortLog" + echo "git diff --stat --summary -M v$last v$new > ../diffstat-$new" + + and then he just cut-and-pastes the output commands after verifying +that they look OK. + + +File: git.info, Node: Finding commits referencing a file with given content, Prev: Creating a changelog and tarball for a software release, Up: Examples + +2.7.6 Finding commits referencing a file with given content +----------------------------------------------------------- + +Somebody hands you a copy of a file, and asks which commits modified a +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-log.html), git-diff-tree(1) +(git-diff-tree.html), and git-hash-object(1) (git-hash-object.html) man +pages may prove helpful. + + +File: git.info, Node: Developing with Git, Next: Sharing development with others, Prev: Exploring Git history, Up: Top + +3 Developing with Git +********************* + +* Menu: + +* 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:: +* Undoing a merge:: +* Fast-forward merges:: +* Fixing mistakes:: +* Ensuring good performance:: +* Ensuring reliability:: + + +File: git.info, Node: Telling Git your name, Next: Creating a new repository, Up: Developing with Git + +3.1 Telling Git your name +========================= + +Before creating any commits, you should introduce yourself to Git. The +easiest way to do so is to use git-config(1) (git-config.html): + + $ git config --global user.name 'Your Name Comes Here' + $ git config --global user.email 'you@yourdomain.example.com' + + Which will add the following to a file named ‘.gitconfig’ in your +home directory: + + [user] + name = Your Name Comes Here + email = you@yourdomain.example.com + + See the "CONFIGURATION FILE" section of git-config(1) +(git-config.html) for details on the configuration file. The file is +plain text, so you can also edit it with your favorite editor. + + +File: git.info, Node: Creating a new repository, Next: How to make a commit, Prev: Telling Git your name, Up: Developing with Git + +3.2 Creating a new repository +============================= + +Creating a new repository from scratch is very easy: + + $ mkdir project + $ cd project + $ git init + + If you have some initial content (say, a tarball): + + $ tar xzvf project.tar.gz + $ cd project + $ git init + $ git add . # include everything below ./ in the first commit: + $ git commit + + +File: git.info, Node: How to make a commit, Next: Creating good commit messages, Prev: Creating a new repository, Up: Developing with Git + +3.3 How to make a commit +======================== + +Creating a new commit takes three steps: + + 1. Making some changes to the working directory using your favorite + editor. + + 2. Telling Git about your changes. + + 3. Creating the commit using the content you told Git about in step 2. + + In practice, you can interleave and repeat steps 1 and 2 as many +times as you want: in order to keep track of what you want committed at +step 3, Git maintains a snapshot of the tree’s contents in a special +staging area called "the index." + + At the beginning, the content of the index will be identical to that +of the HEAD. The command ‘git diff --cached’, which shows the difference +between the HEAD and the index, should therefore produce no output at +that point. + + Modifying the index is easy: + + To update the index with the contents of a new or modified file, use + + $ git add path/to/file + + To remove a file from the index and from the working tree, use + + $ git rm path/to/file + + After each step you can verify that + + $ git diff --cached + + always shows the difference between the HEAD and the index file—this +is what you’d commit if you created the commit now—and that + + $ git diff + + shows the difference between the working tree and the index file. + + Note that ‘git add’ always adds just the current contents of a file +to the index; further changes to the same file will be ignored unless +you run ‘git add’ on the file again. + + When you’re ready, just run + + $ git commit + + and Git will prompt you for a commit message and then create the new +commit. Check to make sure it looks like what you expected with + + $ git show + + As a special shortcut, + + $ git commit -a + + will update the index with any files that you’ve modified or removed +and create a commit, all in one step. + + A number of commands are useful for keeping track of what you’re +about to commit: + + $ git diff --cached # difference between HEAD and the index; what + # would be committed if you ran "commit" now. + $ git diff # difference between the index file and your + # working directory; changes that would not + # be included if you ran "commit" now. + $ git diff HEAD # difference between HEAD and working tree; what + # would be committed if you ran "commit -a" now. + $ git status # a brief per-file summary of the above. + + You can also use git-gui(1) (git-gui.html) to create commits, view +changes in the index and the working tree files, and individually select +diff hunks for inclusion in the index (by right-clicking on the diff +hunk and choosing "Stage Hunk For Commit"). + + +File: git.info, Node: Creating good commit messages, Next: Ignoring files, Prev: How to make a commit, Up: Developing with Git + +3.4 Creating good commit messages +================================= + +Though not required, it’s a good idea to begin the commit message with a +single short (less than 50 character) line summarizing the change, +followed by a blank line and then a more thorough description. The text +up to the first blank line in a commit message is treated as the commit +title, and that title is used throughout Git. For example, +git-format-patch(1) (git-format-patch.html) turns a commit into email, +and it uses the title on the Subject line and the rest of the commit in +the body. + + +File: git.info, Node: Ignoring files, Next: How to merge, Prev: Creating good commit messages, Up: Developing with Git + +3.5 Ignoring files +================== + +A project will often generate files that you do _not_ want to track with +Git. This typically includes files generated by a build process or +temporary backup files made by your editor. Of course, _not_ tracking +files with Git is just a matter of _not_ calling ‘git add’ on them. But +it quickly becomes annoying to have these untracked files lying around; +e.g. they make ‘git add .’ practically useless, and they keep showing +up in the output of ‘git status’. + + You can tell Git to ignore certain files by creating a file called +‘.gitignore’ in the top level of your working directory, with contents +such as: + + # Lines starting with '#' are considered comments. + # Ignore any file named foo.txt. + foo.txt + # Ignore (generated) html files, + *.html + # except foo.html which is maintained by hand. + !foo.html + # Ignore objects and archives. + *.[oa] + + See gitignore(5) (gitignore.html) for a detailed explanation of the +syntax. You can also place .gitignore files in other directories in +your working tree, and they will apply to those directories and their +subdirectories. The ‘.gitignore’ files can be added to your repository +like any other files (just run ‘git add .gitignore’ and ‘git commit’, as +usual), which is convenient when the exclude patterns (such as patterns +matching build output files) would also make sense for other users who +clone your repository. + + If you wish the exclude patterns to affect only certain repositories +(instead of every repository for a given project), you may instead put +them in a file in your repository named ‘.git/info/exclude’, or in any +file specified by the ‘core.excludesFile’ configuration variable. Some +Git commands can also take exclude patterns directly on the command +line. See gitignore(5) (gitignore.html) for the details. + + +File: git.info, Node: How to merge, Next: Resolving a merge, Prev: Ignoring files, Up: Developing with Git + +3.6 How to merge +================ + +You can rejoin two diverging branches of development using git-merge(1) +(git-merge.html): + + $ git merge branchname + + merges the development in the branch ‘branchname’ into the current +branch. + + A merge is made by combining the changes made in ‘branchname’ and the +changes made up to the latest commit in your current branch since their +histories forked. The work tree is overwritten by the result of the +merge when this combining is done cleanly, or overwritten by a +half-merged results when this combining results in conflicts. +Therefore, if you have uncommitted changes touching the same files as +the ones impacted by the merge, Git will refuse to proceed. Most of the +time, you will want to commit your changes before you can merge, and if +you don’t, then git-stash(1) (git-stash.html) can take these changes +away while you’re doing the merge, and reapply them afterwards. + + If the changes are independent enough, Git will automatically +complete the merge and commit the result (or reuse an existing commit in +case of fast-forward (*note Fast-forward merges::), see below). On the +other hand, if there are conflicts—for example, if the same file is +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 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. + + Conflict markers are left in the problematic files, and after you +resolve the conflicts manually, you can update the index with the +contents and run Git commit, as you normally would when creating a new +file. + + If you examine the resulting commit using gitk, you will see that it +has two parents, one pointing to the top of the current branch, and one +to the top of the other branch. + + +File: git.info, Node: Resolving a merge, Next: Undoing a merge, Prev: How to merge, Up: Developing with Git + +3.7 Resolving a merge +===================== + +When a merge isn’t resolved automatically, Git leaves the index and 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(1) +(git-commit.html) will fail: + + $ git commit + file.txt: needs merge + + Also, git-status(1) (git-status.html) 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: + +* Menu: + +* Getting conflict-resolution help during a merge:: + + +File: git.info, Node: Getting conflict-resolution help during a merge, Up: Resolving a merge + +3.7.1 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 git-diff(1) (git-diff.html) shows only the +conflicts. It uses an unusual syntax: + + $ git diff + diff --cc file.txt + index 802992c,2b60207..0000000 + --- a/file.txt + +++ b/file.txt + @@@ -1,1 -1,1 +1,5 @@@ + ++<<<<<<< HEAD:file.txt + +Hello world + ++======= + + Goodbye + ++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt + + Recall that the commit which will be committed after we resolve this +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. + + 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. + $ git show :3:file.txt # the version from MERGE_HEAD. + + When you ask git-diff(1) (git-diff.html) to show the conflicts, it +runs a three-way diff between the conflicted merge results in the work +tree with stages 2 and 3 to show only hunks whose contents come from +both sides, mixed (in other words, when a hunk’s merge results come only +from stage 2, that part is not conflicting and is not shown. Same for +stage 3). + + 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 git-diff-files(1) (git-diff-files.html) 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 + diff --cc file.txt + index 802992c,2b60207..0000000 + --- a/file.txt + +++ b/file.txt + @@@ -1,1 -1,1 +1,1 @@@ + - Hello world + -Goodbye + ++Goodbye world + + 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. + + 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 git-log(1) (git-log.html) and gitk(1) (gitk.html) commands also +provide special help for merges: + + $ git log --merge + $ gitk --merge + + These will display all commits which exist only on HEAD or on +MERGE_HEAD, and which touch an unmerged file. + + You may also use git-mergetool(1) (git-mergetool.html), which lets +you merge the unmerged files using external tools such as Emacs or +kdiff3. + + Each time you resolve the conflicts in a file and update the index: + + $ git add file.txt + + the different stages of that file will be "collapsed", after which +‘git diff’ will (by default) no longer show diffs for that file. + + +File: git.info, Node: Undoing a merge, Next: Fast-forward merges, Prev: Resolving a merge, Up: Developing with Git + +3.8 Undoing a merge +=================== + +If you get stuck and decide to just give up and throw the whole mess +away, you can always return to the pre-merge state with + + $ git merge --abort + + Or, if you’ve already committed the merge that you want to throw +away, + + $ git reset --hard ORIG_HEAD + + However, this last command can be dangerous in some cases—never throw +away a commit you have already committed if that commit may itself have +been merged into another branch, as doing so may confuse further merges. + + +File: git.info, Node: Fast-forward merges, Next: Fixing mistakes, Prev: Undoing a merge, Up: Developing with Git + +3.9 Fast-forward merges +======================= + +There is one special case not mentioned above, which is treated +differently. Normally, a merge results in a merge commit, with two +parents, one pointing at each of the two lines of development that were +merged. + + However, if the current branch is an ancestor of the other—so every +commit present in the current branch is already contained in the other +branch—then Git just performs a "fast-forward"; the head of the current +branch is moved forward to point at the head of the merged-in branch, +without any new commits being created. + + +File: git.info, Node: Fixing mistakes, Next: Ensuring good performance, Prev: Fast-forward merges, Up: Developing with Git + +3.10 Fixing mistakes +==================== + +If you’ve messed up the working tree, but haven’t yet committed your +mistake, you can return the entire working tree to the last committed +state with + + $ git restore --staged --worktree :/ + + If you make a commit that you later wish you hadn’t, there are two +fundamentally different ways to fix the problem: + + 1. You can create a new commit that undoes whatever was done by the + old commit. This is the correct thing if your mistake has already + been made public. + + 2. You can go back and modify the old commit. You should never do + this if you have already made the history public; Git does not + normally expect the "history" of a project to change, and cannot + correctly perform repeated merges from a branch that has had its + history changed. + +* Menu: + +* 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:: + + +File: git.info, Node: Fixing a mistake with a new commit, Next: Fixing a mistake by rewriting history, Up: Fixing mistakes + +3.10.1 Fixing a mistake with a new commit +----------------------------------------- + +Creating a new commit that reverts an earlier change is very easy; just +pass the git-revert(1) (git-revert.html) command a reference to the bad +commit; for example, to revert the most recent commit: + + $ git revert HEAD + + This will create a new commit which undoes the change in HEAD. You +will be given a chance to edit the commit message for the new commit. + + You can also revert an earlier change, for example, the next-to-last: + + $ 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 (*note Resolving a +merge::). + + +File: git.info, Node: Fixing a mistake by rewriting history, Next: Checking out an old version of a file, Prev: Fixing a mistake with a new commit, Up: Fixing mistakes + +3.10.2 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’ (*note Undoing a merge::). + + 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 (*note How to make a 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) (git-revert.html) +instead in 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 (*note +Rewriting history and maintaining patch series::). + + +File: git.info, Node: Checking out an old version of a file, Next: Temporarily setting aside work in progress, Prev: Fixing a mistake by rewriting history, Up: Fixing mistakes + +3.10.3 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 git-restore(1) +(git-restore.html). The command + + $ git restore --source=HEAD^ path/to/file + + replaces path/to/file by the contents it had in the commit HEAD^, and +also updates the index to match. It does not change branches. + + If you just want to look at an old version of the file, without +modifying the working directory, you can do that with git-show(1) +(git-show.html): + + $ git show HEAD^:path/to/file + + which will display the given version of the file. + + +File: git.info, Node: Temporarily setting aside work in progress, Prev: Checking out an old version of a file, Up: Fixing mistakes + +3.10.4 Temporarily setting aside work in progress +------------------------------------------------- + +While you are in the middle of working on something complicated, you +find an unrelated but obvious and trivial bug. You would like to fix it +before continuing. You can use git-stash(1) (git-stash.html) to save +the current state of your work, and after fixing the bug (or, optionally +after doing so on a different branch and then coming back), unstash the +work-in-progress changes. + + $ git stash push -m "work in progress for foo feature" + + This command will save your changes away to the ‘stash’, and reset +your working tree and the index to match the tip of your current branch. +Then you can make your fix as usual. + + ... edit and test ... + $ git commit -a -m "blorpl: typofix" + + After that, you can go back to what you were working on with ‘git +stash pop’: + + $ git stash pop + + +File: git.info, Node: Ensuring good performance, Next: Ensuring reliability, Prev: Fixing mistakes, Up: Developing with Git + +3.11 Ensuring good performance +============================== + +On large repositories, Git depends on compression to keep the history +information from taking up too much space on disk or in memory. Some +Git commands may automatically run git-gc(1) (git-gc.html), so you don’t +have to worry about running it manually. However, compressing a large +repository may take a while, so you may want to call ‘gc’ explicitly to +avoid automatic compression kicking in when it is not convenient. + + +File: git.info, Node: Ensuring reliability, Prev: Ensuring good performance, Up: Developing with Git + +3.12 Ensuring reliability +========================= + +* Menu: + +* Checking the repository for corruption:: +* Recovering lost changes:: + + +File: git.info, Node: Checking the repository for corruption, Next: Recovering lost changes, Up: Ensuring reliability + +3.12.1 Checking the repository for corruption +--------------------------------------------- + +The git-fsck(1) (git-fsck.html) command runs a number of +self-consistency checks on the repository, and reports on any problems. +This may take some time. + + $ git fsck + dangling commit 7281251ddd2a61e38657c827739c57015671a6b3 + dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63 + dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5 + dangling blob 218761f9d90712d37a9c5e36f406f92202db07eb + dangling commit bf093535a34a4d35731aa2bd90fe6b176302f14f + dangling commit 8e4bec7f2ddaa268bef999853c25755452100f8e + dangling tree d50bb86186bf27b681d25af89d3b5b68382e4085 + dangling tree b24c2473f1fd3d91352a624795be026d64c8841f + ... + + You will see informational messages on dangling objects. They are +objects that still exist in the repository but are no longer referenced +by any of your branches, and can (and will) be removed after a while +with ‘gc’. You can run ‘git fsck --no-dangling’ to suppress these +messages, and still view real errors. + + +File: git.info, Node: Recovering lost changes, Prev: Checking the repository for corruption, Up: Ensuring reliability + +3.12.2 Recovering lost changes +------------------------------ + +* Menu: + +* Reflogs:: +* Examining dangling objects:: + + +File: git.info, Node: Reflogs, Next: Examining dangling objects, Up: Recovering lost changes + +3.12.2.1 Reflogs +................ + +Say you modify a branch with ‘git reset --hard’ (*note Fixing +mistakes::), 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 +old history using, for example, + + $ git log master@{1} + + This lists the commits reachable from the previous version of the +‘master’ branch head. This syntax can be used with any Git command that +accepts a commit, not just with ‘git log’. Some other examples: + + $ git show master@{2} # See where the branch pointed 2, + $ git show master@{3} # 3, ... changes ago. + $ gitk master@{yesterday} # See where it pointed yesterday, + $ gitk master@{"1 week ago"} # ... or last week + $ git log --walk-reflogs master # show reflog entries for master + + A separate reflog is kept for the HEAD, so + + $ git show HEAD@{"1 week ago"} + + will show what HEAD pointed to one week ago, not what the current +branch pointed to one week ago. This allows you to see the history of +what you’ve checked out. + + The reflogs are kept by default for 30 days, after which they may be +pruned. See git-reflog(1) (git-reflog.html) and git-gc(1) (git-gc.html) +to learn how to control this pruning, and see the "SPECIFYING REVISIONS" +section of gitrevisions(7) (gitrevisions.html) for details. + + Note that the reflog history is very different from normal Git +history. While normal history is shared by every repository that works +on the same project, the reflog history is not shared: it tells you only +about how the branches in your local repository have changed over time. + + +File: git.info, Node: Examining dangling objects, Prev: Reflogs, Up: Recovering lost changes + +3.12.2.2 Examining dangling objects +................................... + +In some situations the reflog may not be able to save you. For example, +suppose you delete a branch, then realize you need the history it +contained. The reflog is also deleted; however, if you have not yet +pruned the repository, then you may still be able to find the lost +commits in the dangling objects that ‘git fsck’ reports. See *note +Dangling objects:: for the details. + + $ git fsck + dangling commit 7281251ddd2a61e38657c827739c57015671a6b3 + dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63 + dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5 + ... + + You can examine one of those dangling commits with, for example, + + $ gitk 7281251ddd --not --all + + which does what it sounds like: it says that you want to see the +commit history that is described by the dangling commit(s), but not the +history that is described by all your existing branches and tags. Thus +you get exactly the history reachable from that commit that is lost. +(And notice that it might not be just one commit: we only report the +"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. + + +File: git.info, Node: Sharing development with others, Next: Rewriting history and maintaining patch series, Prev: Developing with Git, Up: Top + +4 Sharing development with others +********************************* + +* Menu: + +* Getting updates with git pull:: +* Submitting patches to a project:: +* Importing patches to a project:: +* Public Git repositories:: +* How to get a Git repository with minimal history:: +* Examples: Examples <1>. + + +File: git.info, Node: Getting updates with git pull, Next: Submitting patches to a project, Up: Sharing development with others + +4.1 Getting updates with git pull +================================= + +After you clone a repository and commit 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 +(*note Updating a repository with git fetch::) with git-fetch(1) +(git-fetch.html), and how to merge two branches. So you can merge in +changes from the original repository’s master branch with: + + $ git fetch + $ git merge origin/master + + However, the git-pull(1) (git-pull.html) command provides a way to do +this in one step: + + $ git pull origin master + + In fact, if you have ‘master’ checked out, then this branch has been +configured by ‘git clone’ to get changes from the HEAD branch of the +origin repository. So often you can accomplish the above with just a +simple + + $ git pull + + This command will fetch changes from the remote branches to your +remote-tracking branches ‘origin/*’, and merge the default branch into +the current branch. + + More generally, a branch that is created from a remote-tracking +branch will pull by default from that branch. See the descriptions of +the ‘branch.<name>.remote’ and ‘branch.<name>.merge’ options in +git-config(1) (git-config.html), and the discussion of the ‘--track’ +option in git-checkout(1) (git-checkout.html), to learn how to control +these defaults. + + In addition to saving you keystrokes, ‘git pull’ also helps you by +producing a default commit message documenting the branch and repository +that you pulled from. + + (But note that no such commit will be created in the case of a +fast-forward (*note Fast-forward merges::); instead, your branch will +just be updated to point to the latest commit from the upstream branch.) + + The ‘git pull’ command can also be given ‘.’ as the "remote" +repository, in which case it just merges in a branch from the current +repository; so the commands + + $ git pull . branch + $ git merge branch + + are roughly equivalent. + + +File: git.info, Node: Submitting patches to a project, Next: Importing patches to a project, Prev: Getting updates with git pull, Up: Sharing development with others + +4.2 Submitting patches to a project +=================================== + +If you just have a few changes, the simplest way to submit them may just +be to send them as patches in email: + + First, use git-format-patch(1) (git-format-patch.html); for example: + + $ git format-patch origin + + will produce a numbered series of files in the current directory, one +for each patch in the current branch but not in ‘origin/HEAD’. + + ‘git format-patch’ can include an initial "cover letter". You can +insert commentary on individual patches after the three dash line which +‘format-patch’ places after the commit message but before the patch +itself. If you use ‘git notes’ to track your cover letter material, +‘git format-patch --notes’ will include the commit’s notes in a similar +manner. + + You can then import these into your mail client and send them by +hand. However, if you have a lot to send at once, you may prefer to use +the git-send-email(1) (git-send-email.html) script to automate the +process. Consult the mailing list for your project first to determine +their requirements for submitting patches. + + +File: git.info, Node: Importing patches to a project, Next: Public Git repositories, Prev: Submitting patches to a project, Up: Sharing development with others + +4.3 Importing patches to a project +================================== + +Git also provides a tool called git-am(1) (git-am.html) (am stands for +"apply mailbox"), for importing such an emailed series of patches. Just +save all of the patch-containing messages, in order, into a single +mailbox file, say ‘patches.mbox’, then run + + $ git am -3 patches.mbox + + Git will apply each patch in order; if any conflicts are found, it +will stop, and you can fix the conflicts as described in "Resolving a +merge (*note Resolving a merge::)". (The ‘-3’ option tells Git to +perform a merge; if you would prefer it just to abort and leave your +tree and index untouched, you may omit that option.) + + Once the index is updated with the results of the conflict +resolution, instead of creating a new commit, just run + + $ git am --continue + + and Git will create the commit for you and continue applying the +remaining patches from the mailbox. + + The final result will be a series of commits, one for each patch in +the original mailbox, with authorship and commit log message each taken +from the message containing each patch. + + +File: git.info, Node: Public Git repositories, Next: How to get a Git repository with minimal history, Prev: Importing patches to a project, Up: Sharing development with others + +4.4 Public Git repositories +=========================== + +Another way to submit changes to a project is to tell the maintainer of +that project to pull the changes from your repository using git-pull(1) +(git-pull.html). In the section "Getting updates with ‘git pull’ (*note +Getting updates with git pull::)" we described this as a way to get +updates from the "main" repository, but it works just as well in the +other direction. + + If you and the maintainer both have accounts on the same machine, +then you can just pull changes from each other’s repositories directly; +commands that accept repository URLs as arguments will also accept a +local directory name: + + $ git clone /path/to/repository + $ git pull /path/to/other/repository + + or an ssh URL: + + $ git clone ssh://yourhost/~you/repository + + For projects with few developers, or for synchronizing a few private +repositories, this may be all you need. + + However, the more common way to do this is to maintain a separate +public repository (usually on a different host) for others to pull +changes from. This is usually more convenient, and allows you to +cleanly separate private work in progress from publicly visible work. + + You will continue to do your day-to-day work in your personal +repository, but periodically "push" changes from your personal +repository into your public repository, allowing other developers to +pull from that repository. So the flow of changes, in a situation where +there is one other developer with a public repository, looks like this: + + you push + your personal repo ------------------> your public repo + ^ | + | | + | you pull | they pull + | | + | | + | they push V + their public repo <------------------- their repo + + We explain how to do this in the following sections. + +* Menu: + +* 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:: + + +File: git.info, Node: Setting up a public repository, Next: Exporting a Git repository via the Git protocol, Up: Public Git repositories + +4.4.1 Setting up a public repository +------------------------------------ + +Assume your personal repository is in the directory ‘~/proj’. We first +create a new clone of the repository and tell ‘git daemon’ that it is +meant to be public: + + $ git clone --bare ~/proj proj.git + $ touch proj.git/git-daemon-export-ok + + The resulting directory proj.git contains a "bare" git repository—it +is just the contents of the ‘.git’ directory, without any files checked +out around it. + + Next, copy ‘proj.git’ to the server where you plan to host the public +repository. You can use scp, rsync, or whatever is most convenient. + + +File: git.info, Node: Exporting a Git repository via the Git protocol, Next: Exporting a git repository via HTTP, Prev: Setting up a public repository, Up: Public Git repositories + +4.4.2 Exporting a Git repository via the Git protocol +----------------------------------------------------- + +This is the preferred method. + + If someone else administers the server, they should tell you what +directory to put the repository in, and what ‘git://’ URL it will appear +at. You can then skip to the section "Pushing changes to a public +repository (*note Pushing changes to a public repository::)", below. + + Otherwise, all you need to do is start git-daemon(1) +(git-daemon.html); it will listen on port 9418. By default, it will +allow access to any directory that looks like a Git directory and +contains the magic file git-daemon-export-ok. Passing some directory +paths as ‘git daemon’ arguments will further restrict the exports to +those paths. + + You can also run ‘git daemon’ as an inetd service; see the +git-daemon(1) (git-daemon.html) man page for details. (See especially +the examples section.) + + +File: git.info, Node: Exporting a git repository via HTTP, Next: Pushing changes to a public repository, Prev: Exporting a Git repository via the Git protocol, Up: Public Git repositories + +4.4.3 Exporting a git repository via HTTP +----------------------------------------- + +The Git protocol gives better performance and reliability, but on a host +with a web server set up, HTTP exports may be simpler to set up. + + All you need to do is place the newly created bare Git repository in +a directory that is exported by the web server, and make some +adjustments to give web clients some extra information they need: + + $ mv proj.git /home/you/public_html/proj.git + $ cd proj.git + $ git --bare update-server-info + $ mv hooks/post-update.sample hooks/post-update + + (For an explanation of the last two lines, see +git-update-server-info(1) (git-update-server-info.html) and githooks(5) +(githooks.html).) + + Advertise the URL of ‘proj.git’. Anybody else should then be able to +clone or pull from that URL, for example with a command line like: + + $ git clone http://yourserver.com/~you/proj.git + + (See also setup-git-server-over-http +(howto/setup-git-server-over-http.html) for a slightly more +sophisticated setup using WebDAV which also allows pushing over HTTP.) + + +File: git.info, Node: Pushing changes to a public repository, Next: What to do when a push fails, Prev: Exporting a git repository via HTTP, Up: Public Git repositories + +4.4.4 Pushing changes to a public repository +-------------------------------------------- + +Note that the two techniques outlined above (exporting via http (*note +Exporting a git repository via HTTP::) or git (*note Exporting a Git +repository via the Git protocol::)) allow other 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) (git-push.html) 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 (*note Fast-forward merges::); see the following +section for details on handling this case. + + Note that the target of a ‘push’ is normally a bare (*note +[def_bare_repository]::) repository. You can also push to a repository +that has a checked-out working tree, but a push to update the currently +checked-out branch is denied by default to prevent confusion. See the +description of the receive.denyCurrentBranch option in git-config(1) +(git-config.html) for details. + + As with ‘git fetch’, you may also set up configuration options to +save typing; so, for example: + + $ git remote add public-repo ssh://yourserver.com/~you/proj.git + + adds the following to ‘.git/config’: + + [remote "public-repo"] + url = yourserver.com:proj.git + fetch = +refs/heads/*:refs/remotes/example/* + + which lets you do the same 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) (git-config.html) for details. + + +File: git.info, Node: What to do when a push fails, Next: Setting up a shared repository, Prev: Pushing changes to a public repository, Up: Public Git repositories + +4.4.5 What to do when a push fails +---------------------------------- + +If a push would not result in a fast-forward (*note Fast-forward +merges::) of the remote branch, then it will fail with an error like: + + ! [rejected] master -> master (non-fast-forward) + error: failed to push some refs to '...' + hint: Updates were rejected because the tip of your current branch is behind + hint: its remote counterpart. Integrate the remote changes (e.g. + hint: 'git pull ...') before pushing again. + hint: See the 'Note about fast-forwards' in 'git push --help' for details. + + 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 *note Fixing a mistake by rewriting history::), or + + • use ‘git rebase’ to rebase any already-published commits (as in + *note Keeping a patch series up to date 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 + + Note the addition of the ‘+’ sign. Alternatively, you can use the +‘-f’ flag to force the remote update, as in: + + $ git push -f 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 descendant of the commit that it pointed to +before. By forcing a push in this situation, you break that convention. +(See *note 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: +either by a pull, or by a fetch followed by a rebase; see the next +section (*note Setting up a shared repository::) and gitcvs-migration(7) +(gitcvs-migration.html) for more. + + +File: git.info, Node: Setting up a shared repository, Next: Allowing web browsing of a repository, Prev: What to do when a push fails, Up: Public Git repositories + +4.4.6 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 gitcvs-migration(7) +(gitcvs-migration.html) for instructions on how to set this up. + + However, while there is nothing wrong with Git’s support for shared +repositories, this mode of operation is not generally recommended, +simply because the mode of collaboration that Git supports—by exchanging +patches and pulling from public repositories—has so many advantages over +the central shared repository: + + • Git’s ability to quickly import and merge patches allows a single + maintainer to process incoming changes even at very high rates. + And when that becomes too much, ‘git pull’ provides an easy way for + that maintainer to delegate this job to other maintainers while + still allowing optional review of incoming changes. + + • Since every developer’s repository has the same complete copy of + the project history, no repository is special, and it is trivial + for another developer to take over maintenance of a project, either + by mutual agreement, or because a maintainer becomes unresponsive + or difficult to work with. + + • The lack of a central group of "committers" means there is less + need for formal decisions about who is "in" and who is "out". + + +File: git.info, Node: Allowing web browsing of a repository, Prev: Setting up a shared repository, Up: Public Git repositories + +4.4.7 Allowing web browsing of a repository +------------------------------------------- + +The gitweb cgi script provides users an easy way to browse your +project’s revisions, file contents and logs without having to install +Git. Features like RSS/Atom feeds and blame/annotation details may +optionally be enabled. + + The git-instaweb(1) (git-instaweb.html) command provides a simple way +to start browsing the repository using gitweb. The default server when +using instaweb is lighttpd. + + See the file gitweb/INSTALL in the Git source tree and gitweb(1) +(gitweb.html) for instructions on details setting up a permanent +installation with a CGI or Perl capable server. + + +File: git.info, Node: How to get a Git repository with minimal history, Next: Examples <1>, Prev: Public Git repositories, Up: Sharing development with others + +4.5 How to get a Git repository with minimal history +==================================================== + +A shallow clone (*note [def_shallow_clone]::), with its truncated +history, is useful when one is interested only in recent history of a +project and getting full history from the upstream is expensive. + + A shallow clone (*note [def_shallow_clone]::) is created by +specifying the git-clone(1) (git-clone.html) ‘--depth’ switch. The +depth can later be changed with the git-fetch(1) (git-fetch.html) +‘--depth’ switch, or full history restored with ‘--unshallow’. + + Merging inside a shallow clone (*note [def_shallow_clone]::) will +work as long as a merge base is in the recent history. Otherwise, it +will be like merging unrelated histories and may have to result in huge +conflicts. This limitation may make such a repository unsuitable to be +used in merge based workflows. + + +File: git.info, Node: Examples <1>, Prev: How to get a Git repository with minimal history, Up: Sharing development with others + +4.6 Examples +============ + +* Menu: + +* Maintaining topic branches for a Linux subsystem maintainer:: + + +File: git.info, Node: Maintaining topic branches for a Linux subsystem maintainer, Up: Examples <1> + +4.6.1 Maintaining topic branches for a Linux subsystem maintainer +----------------------------------------------------------------- + +This describes how Tony Luck uses Git in his role as maintainer of the +IA64 architecture for the Linux kernel. + + He uses two public branches: + + • A "test" tree into which patches are initially placed so that they + can get some exposure when integrated with other ongoing + development. This tree is available to Andrew for pulling into -mm + whenever he wants. + + • A "release" tree into which tested patches are moved for final + sanity checking, and as a vehicle to send them upstream to Linus + (by sending him a "please pull" request.) + + He also uses a set of temporary branches ("topic branches"), each +containing a logical grouping of patches. + + To set this up, first create your work tree by cloning Linus’s public +tree: + + $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git work + $ cd work + + Linus’s tree will be stored in the remote-tracking branch named +origin/master, and can be updated using git-fetch(1) (git-fetch.html); +you can track other public trees using git-remote(1) (git-remote.html) +to set up a "remote" and git-fetch(1) (git-fetch.html) to keep them up +to date; see *note Repositories and Branches::. + + Now create the branches in which you are going to work; these start +out at the current tip of origin/master branch, and should be set up +(using the ‘--track’ option to git-branch(1) (git-branch.html)) to merge +changes in from Linus by default. + + $ git branch --track test origin/master + $ git branch --track release origin/master + + These can be easily kept up to date using git-pull(1) +(git-pull.html). + + $ git switch test && git pull + $ git switch release && git pull + + Important note! If you have any local changes in these branches, +then this merge will create a commit object in the history (with no +local changes Git will simply do a "fast-forward" merge). Many people +dislike the "noise" that this creates in the Linux history, so you +should avoid doing this capriciously in the ‘release’ branch, as these +noisy commits will become part of the permanent history when you ask +Linus to pull from the release branch. + + A few configuration variables (see git-config(1) (git-config.html)) +can make it easy to push both branches to your public tree. (See *note +Setting up a public repository::.) + + $ cat >> .git/config <<EOF + [remote "mytree"] + url = master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux.git + push = release + push = test + EOF + + Then you can push both the test and release trees using git-push(1) +(git-push.html): + + $ git push mytree + + or push just one of the test and release branches using: + + $ git push mytree test + + or + + $ git push mytree release + + Now to apply some patches from the community. Think of a short +snappy name for a branch to hold this patch (or related group of +patches), and create a new branch from a recent stable tag of Linus’s +branch. Picking a stable base for your branch will: 1) help you: by +avoiding inclusion of unrelated and perhaps lightly tested changes 2) +help future bug hunters that use ‘git bisect’ to find problems + + $ git switch -c speed-up-spinlocks v2.6.35 + + Now you apply the patch(es), run some tests, and commit the +change(s). If the patch is a multi-part series, then you should apply +each as a separate commit to this branch. + + $ ... patch ... test ... commit [ ... patch ... test ... commit ]* + + When you are happy with the state of this change, you can merge it +into the "test" branch in preparation to make it public: + + $ git switch test && git merge speed-up-spinlocks + + It is unlikely that you would have any conflicts here … but you might +if you spent a while on this step and had also pulled new versions from +upstream. + + Sometime later when enough time has passed and testing done, you can +pull the same branch into the ‘release’ tree ready to go upstream. This +is where you see the value of keeping each patch (or patch series) in +its own branch. It means that the patches can be moved into the +‘release’ tree in any order. + + $ git switch release && git merge speed-up-spinlocks + + After a while, you will have a number of branches, and despite the +well chosen names you picked for each of them, you may forget what they +are for, or what status they are in. To get a reminder of what changes +are in a specific branch, use: + + $ git log linux..branchname | git shortlog + + To see whether it has already been merged into the test or release +branches, use: + + $ git log test..branchname + + or + + $ git log release..branchname + + (If this branch has not yet been merged, you will see some log +entries. If it has been merged, then there will be no output.) + + Once a patch completes the great cycle (moving from test to release, +then pulled by Linus, and finally coming back into your local +‘origin/master’ branch), the branch for this change is no longer needed. +You detect this when the output from: + + $ git log origin..branchname + + is empty. At this point the branch can be deleted: + + $ git branch -d branchname + + Some changes are so trivial that it is not necessary to create a +separate branch and then merge into each of the test and release +branches. For these changes, just apply directly to the ‘release’ +branch, and then merge that into the ‘test’ branch. + + After pushing your work to ‘mytree’, you can use git-request-pull(1) +(git-request-pull.html) to prepare a "please pull" request message to +send to Linus: + + $ git push mytree + $ git request-pull origin mytree release + + Here are some of the scripts that simplify all this even further. + + ==== update script ==== + # Update a branch in my Git tree. If the branch to be updated + # is origin, then pull from kernel.org. Otherwise merge + # origin/master branch into test|release branch + + case "$1" in + test|release) + git checkout $1 && git pull . origin + ;; + origin) + before=$(git rev-parse refs/remotes/origin/master) + git fetch origin + after=$(git rev-parse refs/remotes/origin/master) + if [ $before != $after ] + then + git log $before..$after | git shortlog + fi + ;; + *) + echo "usage: $0 origin|test|release" 1>&2 + exit 1 + ;; + esac + + ==== merge script ==== + # Merge a branch into either the test or release branch + + pname=$0 + + usage() + { + echo "usage: $pname branch test|release" 1>&2 + exit 1 + } + + git show-ref -q --verify -- refs/heads/"$1" || { + echo "Can't see branch <$1>" 1>&2 + usage + } + + case "$2" in + test|release) + if [ $(git log $2..$1 | wc -c) -eq 0 ] + then + echo $1 already merged into $2 1>&2 + exit 1 + fi + git checkout $2 && git pull . $1 + ;; + *) + usage + ;; + esac + + ==== status script ==== + # report on status of my ia64 Git tree + + gb=$(tput setab 2) + rb=$(tput setab 1) + restore=$(tput setab 9) + + if [ `git rev-list test..release | wc -c` -gt 0 ] + then + echo $rb Warning: commits in release that are not in test $restore + git log test..release + fi + + for branch in `git show-ref --heads | sed 's|^.*/||'` + do + if [ $branch = test -o $branch = release ] + then + continue + fi + + echo -n $gb ======= $branch ====== $restore " " + status= + for ref in test release origin/master + do + if [ `git rev-list $ref..$branch | wc -c` -gt 0 ] + then + status=$status${ref:0:1} + fi + done + case $status in + trl) + echo $rb Need to pull into test $restore + ;; + rl) + echo "In test" + ;; + l) + echo "Waiting for linus" + ;; + "") + echo $rb All done $restore + ;; + *) + echo $rb "<$status>" $restore + ;; + esac + git log origin/master..$branch | git shortlog + done + + +File: git.info, Node: Rewriting history and maintaining patch series, Next: Advanced branch management, Prev: Sharing development with others, Up: Top + +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. + +* Menu: + +* 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:: +* Using interactive rebases:: +* Other tools:: +* Problems with rewriting history:: +* Why bisecting merge commits can be harder than bisecting linear history:: + + +File: git.info, Node: Creating the perfect patch series, Next: Keeping a patch series up to date using git rebase, Up: Rewriting history and maintaining patch series + +5.1 Creating the perfect patch series +===================================== + +Suppose you are a contributor to a large project, and you want to add a +complicated feature, and to present it to the other developers in a way +that makes it easy for them to read your changes, verify that they are +correct, and understand why you made each change. + + If you present all of your changes as a single patch (or commit), +they may find that it is too much to digest all at once. + + If you present them with the entire history of your work, complete +with mistakes, corrections, and dead ends, they may be overwhelmed. + + So the ideal is usually to produce a series of patches such that: + + 1. Each patch can be applied in order. + + 2. Each patch includes a single logical change, together with a + message explaining the change. + + 3. No patch introduces a regression: after applying any initial part + of the series, the resulting project still compiles and works, and + has no bugs that it didn’t have before. + + 4. The complete series produces the same end result as your own + (probably much messier!) development process did. + + We will introduce some tools that can help you do this, explain how +to use them, and then explain some of the problems that can arise +because you are rewriting history. + + +File: git.info, Node: Keeping a patch series up to date using git rebase, Next: Rewriting a single commit, Prev: Creating the perfect patch series, Up: Rewriting history and maintaining patch series + +5.2 Keeping a patch series up to date using git rebase +====================================================== + +Suppose that you create a branch ‘mywork’ on a remote-tracking branch +‘origin’, and create some commits on top of it: + + $ git switch -c mywork origin + $ vi file.txt + $ git commit + $ vi otherfile.txt + $ 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 + \ + a--b--c <-- 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 +git-rebase(1) (git-rebase.html): + + $ git switch mywork + $ git rebase origin + + This will remove each of your commits from mywork, temporarily saving +them as patches (in a directory named ‘.git/rebase-apply’), update +mywork to 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 +add’ to update the index with those contents, and then, instead of +running ‘git commit’, just run + + $ 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 + + If you need to reorder or edit a number of commits in a branch, it +may be easier to use ‘git rebase -i’, which allows you to reorder and +squash commits, as well as marking them for individual editing during +the rebase. See *note Using interactive rebases:: for details, and +*note Reordering or selecting from a patch series:: for alternatives. + + +File: git.info, Node: Rewriting a single commit, Next: Reordering or selecting from a patch series, Prev: Keeping a patch series up to date using git rebase, Up: Rewriting history and maintaining patch series + +5.3 Rewriting a single commit +============================= + +We saw in *note 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. This +is useful for fixing typos in your last commit, or for adjusting the +patch contents of a poorly staged commit. + + If you need to amend commits from deeper in your history, you can use +interactive rebase’s ‘edit’ instruction (*note Using interactive +rebases::). + + +File: git.info, Node: Reordering or selecting from a patch series, Next: Using interactive rebases, Prev: Rewriting a single commit, Up: Rewriting history and maintaining patch series + +5.4 Reordering or selecting from a patch series +=============================================== + +Sometimes you want to edit a commit deeper in your history. One +approach is to use ‘git format-patch’ to create a series of patches and +then reset the state to before the patches: + + $ git format-patch origin + $ git reset --hard origin + + Then modify, reorder, or eliminate patches as needed before applying +them again with git-am(1) (git-am.html): + + $ git am *.patch + + +File: git.info, Node: Using interactive rebases, Next: Other tools, Prev: Reordering or selecting from a patch series, Up: Rewriting history and maintaining patch series + +5.5 Using interactive rebases +============================= + +You can also edit a patch series with an interactive rebase. This is +the same as reordering a patch series using ‘format-patch’ (*note +Reordering or selecting from a patch series::), so use whichever +interface you like best. + + Rebase your current HEAD on the last commit you want to retain as-is. +For example, if you want to reorder the last 5 commits, use: + + $ git rebase -i HEAD~5 + + This will open your editor with a list of steps to be taken to +perform your rebase. + + pick deadbee The oneline of this commit + pick fa1afe1 The oneline of the next commit + ... + + # Rebase c0ffeee..deadbee onto c0ffeee + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # + # These lines can be re-ordered; they are executed from top to bottom. + # + # If you remove a line here THAT COMMIT WILL BE LOST. + # + # However, if you remove everything, the rebase will be aborted. + # + # Note that empty commits are commented out + + As explained in the comments, you can reorder commits, squash them +together, edit commit messages, etc. by editing the list. Once you are +satisfied, save the list and close your editor, and the rebase will +begin. + + The rebase will stop where ‘pick’ has been replaced with ‘edit’ or +when a step in the list fails to mechanically resolve conflicts and +needs your help. When you are done editing and/or resolving conflicts +you can continue with ‘git rebase --continue’. If you decide that +things are getting too hairy, you can always bail out with ‘git rebase +--abort’. Even after the rebase is complete, you can still recover the +original branch by using the reflog (*note Reflogs::). + + For a more detailed discussion of the procedure and additional tips, +see the "INTERACTIVE MODE" section of git-rebase(1) (git-rebase.html). + + +File: git.info, Node: Other tools, Next: Problems with rewriting history, Prev: Using interactive rebases, Up: Rewriting history and maintaining patch series + +5.6 Other tools +=============== + +There are numerous other tools, such as StGit, which exist for the +purpose of maintaining a patch series. These are outside of the scope +of this manual. + + +File: git.info, Node: Problems with rewriting history, Next: Why bisecting merge commits can be harder than bisecting linear history, Prev: Other tools, Up: Rewriting history and maintaining patch series + +5.7 Problems with rewriting history +=================================== + +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 +two developers had independently done the work on the old and new heads +in parallel. At this point, if someone attempts to merge the new head +in to their branch, Git will attempt to merge together the two (old and +new) lines of development, instead of trying to replace the old by the +new. The results are likely to be unexpected. + + You may still choose to publish branches whose history is rewritten, +and it may be useful for others to be able to fetch those branches in +order to examine or test them, but they should not attempt to pull such +branches into their own work. + + For true distributed development that supports proper merging, +published branches should never be rewritten. + + +File: git.info, Node: Why bisecting merge commits can be harder than bisecting linear history, Prev: Problems with rewriting history, Up: Rewriting history and maintaining patch series + +5.8 Why bisecting merge commits can be harder than bisecting linear history +=========================================================================== + +The git-bisect(1) (git-bisect.html) command correctly handles history +that includes merge commits. However, when the commit that it finds is +a merge commit, the user may need to work harder than usual to figure +out why that commit introduced a problem. + + Imagine this history: + + ---Z---o---X---...---o---A---C---D + \ / + o---o---Y---...---o---B + + Suppose that on the upper line of development, the meaning of one of +the functions that exists at Z is changed at commit X. The commits from +Z leading to A change both the function’s implementation and all calling +sites that exist at Z, as well as new calling sites they add, to be +consistent. There is no bug at A. + + Suppose that in the meantime on the lower line of development +somebody adds a new calling site for that function at commit Y. The +commits from Z leading to B all assume the old semantics of that +function and the callers and the callee are consistent with each other. +There is no bug at B, either. + + Suppose further that the two development lines merge cleanly at C, so +no conflict resolution is required. + + Nevertheless, the code at C is broken, because the callers added on +the lower line of development have not been converted to the new +semantics introduced on the upper line of development. So if all you +know is that D is bad, that Z is good, and that git-bisect(1) +(git-bisect.html) identifies C as the culprit, how will you figure out +that the problem is due to this change in semantics? + + When the result of a ‘git bisect’ is a non-merge commit, you should +normally be able to discover the problem by examining just that commit. +Developers can make this easy by breaking their changes into small +self-contained commits. That won’t help in the case above, however, +because the problem isn’t obvious from examination of any single commit; +instead, a global view of the development is required. To make matters +worse, the change in semantics in the problematic function may be just +one small part of the changes in the upper line of development. + + On the other hand, if instead of merging at C you had rebased the +history between Z to B on top of A, you would have gotten this linear +history: + + ---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D* + + Bisecting between Z and D* would hit a single culprit commit Y*, and +understanding why Y* was broken would probably be easier. + + Partly for this reason, many experienced Git users, even when working +on an otherwise merge-heavy project, keep the history linear by rebasing +against the latest upstream version before publishing. + + +File: git.info, Node: Advanced branch management, Next: Git concepts, Prev: Rewriting history and maintaining patch series, Up: Top + +6 Advanced branch management +**************************** + +* Menu: + +* Fetching individual branches:: +* git fetch and fast-forwards:: +* Forcing git fetch to do non-fast-forward updates:: +* Configuring remote-tracking branches:: + + +File: git.info, Node: Fetching individual branches, Next: git fetch and fast-forwards, Up: Advanced branch management + +6.1 Fetching individual branches +================================ + +Instead of using git-remote(1) (git-remote.html), you can also choose +just to update one branch at a time, and to store it locally under an +arbitrary name: + + $ git fetch origin todo:my-todo-work + + The first argument, ‘origin’, just tells Git to fetch from the +repository you originally cloned from. The second argument tells Git to +fetch the branch named ‘todo’ from the remote repository, and to store +it locally under the name ‘refs/heads/my-todo-work’. + + You can also fetch branches from other repositories; so + + $ git fetch git://example.com/proj.git master:example-master + + will create a new branch named ‘example-master’ and store in it the +branch named ‘master’ from the repository at the given URL. If you +already have a branch named example-master, it will attempt to +fast-forward (*note Fast-forward merges::) to the commit given by +example.com’s master branch. In more detail: + + +File: git.info, Node: git fetch and fast-forwards, Next: Forcing git fetch to do non-fast-forward updates, Prev: Fetching individual branches, Up: Advanced branch management + +6.2 git fetch and fast-forwards +=============================== + +In the previous example, when updating an existing branch, ‘git fetch’ +checks to make sure that the most recent commit on the remote branch is +a descendant of the most recent commit on your copy of the branch before +updating your copy of the branch to point at the new commit. Git calls +this process a fast-forward (*note Fast-forward merges::). + + 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 +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. + + In that case, you can still force Git to update to the new head, as +described in the following section. However, note that in the situation +above this may mean losing the commits labeled ‘a’ and ‘b’, unless +you’ve already created a reference of your own pointing to them. + + +File: git.info, Node: Forcing git fetch to do non-fast-forward updates, Next: Configuring remote-tracking branches, Prev: git fetch and fast-forwards, Up: Advanced branch management + +6.3 Forcing git fetch to do non-fast-forward updates +==================================================== + +If git fetch fails because the new head of a branch is not a descendant +of the old head, you may force the update with: + + $ git fetch git://example.com/proj.git +master:refs/remotes/example/master + + Note the addition of the ‘+’ sign. Alternatively, you can use the +‘-f’ flag to force updates of all the fetched branches, as in: + + $ git fetch -f origin + + Be aware that commits that the old version of example/master pointed +at may be lost, as we saw in the previous section. + + +File: git.info, Node: Configuring remote-tracking branches, Prev: Forcing git fetch to do non-fast-forward updates, Up: Advanced branch management + +6.4 Configuring remote-tracking branches +======================================== + +We saw above that ‘origin’ is just a shortcut to refer to the repository +that you originally cloned from. This information is stored in Git +configuration variables, which you can see using git-config(1) +(git-config.html): + + $ git config -l + core.repositoryformatversion=0 + core.filemode=true + core.logallrefupdates=true + remote.origin.url=git://git.kernel.org/pub/scm/git/git.git + remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* + branch.master.remote=origin + branch.master.merge=refs/heads/master + + If there are other repositories that you also use frequently, you can +create similar configuration options to save typing; for example, + + $ git remote add example git://example.com/proj.git + + adds the following to ‘.git/config’: + + [remote "example"] + url = git://example.com/proj.git + fetch = +refs/heads/*:refs/remotes/example/* + + Also note that the above configuration can be performed by directly +editing the file ‘.git/config’ instead of using git-remote(1) +(git-remote.html). + + After configuring the remote, the following three commands will do +the same thing: + + $ git fetch git://example.com/proj.git +refs/heads/*:refs/remotes/example/* + $ git fetch example +refs/heads/*:refs/remotes/example/* + $ git fetch example + + See git-config(1) (git-config.html) for more details on the +configuration options mentioned above and git-fetch(1) (git-fetch.html) +for more details on the refspec syntax. + + +File: git.info, Node: Git concepts, Next: Submodules, Prev: Advanced branch management, Up: Top + +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 (*note +[def_object_database]::) and the index (*note [def_index]::). + +* Menu: + +* The Object Database:: +* The index:: + + +File: git.info, Node: The Object Database, Next: The index, Up: Git concepts + +7.1 The Object Database +======================= + +We already saw in *note Understanding History: Commits: Understanding +History; Commits. that all commits are stored under a 40-digit "object +name". In fact, all the information needed to represent the history of +a project is stored in objects with such names. In each case the name +is calculated by taking the SHA-1 hash of the contents of the object. +The SHA-1 hash is a cryptographic hash function. What that means to us +is that it is impossible to find two different objects with the same +name. This has a number of advantages; among others: + + • Git can quickly determine whether two objects are identical or not, + just by comparing names. + + • Since object names are computed the same way in every repository, + the same content stored in two repositories will always be stored + under the same name. + + • Git can detect errors when it reads an object, by checking that the + object’s name is still the SHA-1 hash of its contents. + + (See *note Object storage format:: for the details of the object +formatting and SHA-1 calculation.) + + There are four different types of objects: "blob", "tree", "commit", +and "tag". + + • A "blob" object (*note [def_blob_object]::) is used to store file + data. + + • A "tree" object (*note [def_tree_object]::) ties one or more "blob" + objects into a directory structure. In addition, a tree object can + refer to other tree objects, thus creating a directory hierarchy. + + • A "commit" object (*note [def_commit_object]::) ties such directory + hierarchies together into a directed acyclic graph (*note + [def_DAG]::) of revisions—each commit contains the object name of + exactly one tree designating the directory hierarchy at the time of + the commit. In addition, a commit refers to "parent" commit + objects that describe the history of how we arrived at that + directory hierarchy. + + • A "tag" object (*note [def_tag_object]::) symbolically identifies + and can be used to sign other objects. It contains the object name + and type of another object, a symbolic name (of course!) and, + optionally, a signature. + + The object types in some more detail: + +* Menu: + +* Commit Object:: +* Tree Object:: +* Blob Object:: +* Trust:: +* Tag Object:: +* How Git stores objects efficiently; pack files:: +* Dangling objects:: +* Recovering from repository corruption:: + + +File: git.info, Node: Commit Object, Next: Tree Object, Up: The Object Database + +7.1.1 Commit Object +------------------- + +The "commit" object links a physical state of a tree with a description +of how we got there and why. Use the ‘--pretty=raw’ option to +git-show(1) (git-show.html) or git-log(1) (git-log.html) to examine your +favorite commit: + + $ git show -s --pretty=raw 2be7fcb476 + commit 2be7fcb4764f2dbcee52635b91fedb1b3dcf7ab4 + tree fb3a8bdd0ceddd019615af4d57a53f43d8cee2bf + parent 257a84d9d02e90447b149af58b271c19405edb6a + author Dave Watson <dwatson@mimvista.com> 1187576872 -0400 + committer Junio C Hamano <gitster@pobox.com> 1187591163 -0700 + + Fix misspelling of 'suppress' in docs + + Signed-off-by: Junio C Hamano <gitster@pobox.com> + + As you can see, a commit is defined by: + + • a tree: The SHA-1 name of a tree object (as defined below), + representing the contents of a directory at a certain point in + time. + + • parent(s): The SHA-1 name(s) of some number of commits which + represent the immediately previous step(s) in the history of the + project. The example above has one parent; merge commits may have + more than one. A commit with no parents is called a "root" commit, + and represents the initial revision of a project. Each project + must have at least one root. A project can also have multiple + roots, though that isn’t common (or necessarily a good idea). + + • an author: The name of the person responsible for this change, + together with its date. + + • a committer: The name of the person who actually created the + commit, with the date it was done. This may be different from the + author, for example, if the author was someone who wrote a patch + and emailed it to the person who used it to create the commit. + + • a comment describing this commit. + + Note that a commit does not itself contain any information about what +actually changed; all changes are calculated by comparing the contents +of the tree referred to by this commit with the trees associated with +its parents. In particular, Git does not attempt to record file renames +explicitly, though it can identify cases where the existence of the same +file data at changing paths suggests a rename. (See, for example, the +‘-M’ option to git-diff(1) (git-diff.html)). + + A commit is usually created by git-commit(1) (git-commit.html), which +creates a commit whose parent is normally the current HEAD, and whose +tree is taken from the content currently stored in the index. + + +File: git.info, Node: Tree Object, Next: Blob Object, Prev: Commit Object, Up: The Object Database + +7.1.2 Tree Object +----------------- + +The ever-versatile git-show(1) (git-show.html) command can also be used +to examine tree objects, but git-ls-tree(1) (git-ls-tree.html) will give +you more details: + + $ git ls-tree fb3a8bdd0ce + 100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c .gitignore + 100644 blob 5529b198e8d14decbe4ad99db3f7fb632de0439d .mailmap + 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING + 040000 tree 2fb783e477100ce076f6bf57e4a6f026013dc745 Documentation + 100755 blob 3c0032cec592a765692234f1cba47dfdcc3a9200 GIT-VERSION-GEN + 100644 blob 289b046a443c0647624607d471289b2c7dcd470b INSTALL + 100644 blob 4eb463797adc693dc168b926b6932ff53f17d0b1 Makefile + 100644 blob 548142c327a6790ff8821d67c2ee1eff7a656b52 README + ... + + As you can see, a tree object contains a list of entries, each with a +mode, object type, SHA-1 name, and name, sorted by name. It represents +the contents of a single directory tree. + + The object type may be a blob, representing the contents of a file, +or another tree, representing the contents of a subdirectory. Since +trees and blobs, like all other objects, are named by the SHA-1 hash of +their contents, two trees have the same SHA-1 name if and only if their +contents (including, recursively, the contents of all subdirectories) +are identical. This allows Git to quickly determine the differences +between two related tree objects, since it can ignore any entries with +identical object names. + + (Note: in the presence of submodules, trees may also have commits as +entries. See *note Submodules:: for documentation.) + + Note that the files all have mode 644 or 755: Git actually only pays +attention to the executable bit. + + +File: git.info, Node: Blob Object, Next: Trust, Prev: Tree Object, Up: The Object Database + +7.1.3 Blob Object +----------------- + +You can use git-show(1) (git-show.html) to examine the contents of a +blob; take, for example, the blob in the entry for ‘COPYING’ from the +tree above: + + $ git show 6ff87c4664 + + Note that the only valid version of the GPL as far as this project + is concerned is _this_ particular version of the license (ie v2, not + v2.2 or v3.x or whatever), unless explicitly otherwise stated. + ... + + A "blob" object is nothing but a binary blob of data. It doesn’t +refer to anything else or have attributes of any kind. + + Since the blob is entirely defined by its data, if two files in a +directory tree (or in multiple different versions of the repository) +have the same contents, they will share the same blob object. The +object is totally independent of its location in the directory tree, and +renaming a file does not change the object that file is associated with. + + Note that any tree or blob object can be examined using git-show(1) +(git-show.html) with the <revision>:<path> syntax. This can sometimes +be useful for browsing the contents of a tree that is not currently +checked out. + + +File: git.info, Node: Trust, Next: Tag Object, Prev: Blob Object, Up: The Object Database + +7.1.4 Trust +----------- + +If you receive the SHA-1 name of a blob from one source, and its +contents from another (possibly untrusted) source, you can still trust +that those contents are correct as long as the SHA-1 name agrees. This +is because the SHA-1 is designed so that it is infeasible to find +different contents that produce the same hash. + + Similarly, you need only trust the SHA-1 name of a top-level tree +object to trust the contents of the entire directory that it refers to, +and if you receive the SHA-1 name of a commit from a trusted source, +then you can easily verify the entire history of commits reachable +through parents of that commit, and all of those contents of the trees +referred to by those commits. + + So to introduce some real trust in the system, the only thing you +need to do is to digitally sign just _one_ special note, which includes +the name of a top-level commit. Your digital signature shows others +that you trust that commit, and the immutability of the history of +commits tells others that they can trust the whole history. + + In other words, you can easily validate a whole archive by just +sending out a single email that tells the people the name (SHA-1 hash) +of the top commit, and digitally sign that email using something like +GPG/PGP. + + To assist in this, Git also provides the tag object… + + +File: git.info, Node: Tag Object, Next: How Git stores objects efficiently; pack files, Prev: Trust, Up: The Object Database + +7.1.5 Tag Object +---------------- + +A tag object contains an object, object type, tag name, the name of the +person ("tagger") who created the tag, and a message, which may contain +a signature, as can be seen using git-cat-file(1) (git-cat-file.html): + + $ git cat-file tag v1.5.0 + object 437b1b20df4b356c9342dac8d38849f24ef44f27 + type commit + tag v1.5.0 + tagger Junio C Hamano <junkio@cox.net> 1171411200 +0000 + + GIT 1.5.0 + -----BEGIN PGP SIGNATURE----- + Version: GnuPG v1.4.6 (GNU/Linux) + + iD8DBQBF0lGqwMbZpPMRm5oRAuRiAJ9ohBLd7s2kqjkKlq1qqC57SbnmzQCdG4ui + nLE/L9aUXdWeTFPron96DLA= + =2E+0 + -----END PGP SIGNATURE----- + + See the git-tag(1) (git-tag.html) command to learn how to create and +verify tag objects. (Note that git-tag(1) (git-tag.html) can also be +used to create "lightweight tags", which are not tag objects at all, but +just simple references whose names begin with ‘refs/tags/’). + + +File: git.info, Node: How Git stores objects efficiently; pack files, Next: Dangling objects, Prev: Tag Object, Up: The Object Database + +7.1.6 How Git stores objects efficiently: pack files +---------------------------------------------------- + +Newly created objects are initially created in a file named after the +object’s SHA-1 hash (stored in ‘.git/objects’). + + Unfortunately this system becomes inefficient once a project has a +lot of objects. Try this on an old project: + + $ git count-objects + 6930 objects, 47620 kilobytes + + The first number is the number of objects which are kept in +individual files. The second is the amount of space taken up by those +"loose" objects. + + You can save space and make Git faster by moving these loose objects +in to a "pack file", which stores a group of objects in an efficient +compressed format; the details of how pack files are formatted can be +found in pack format (technical/pack-format.html). + + To put the loose objects into a pack, just run git repack: + + $ git repack + Counting objects: 6020, done. + Delta compression using up to 4 threads. + Compressing objects: 100% (6020/6020), done. + Writing objects: 100% (6020/6020), done. + Total 6020 (delta 4070), reused 0 (delta 0) + + This creates a single "pack file" in .git/objects/pack/ containing +all currently unpacked objects. You can then run + + $ git prune + + to remove any of the "loose" objects that are now contained in the +pack. This will also remove any unreferenced objects (which may be +created when, for example, you use ‘git reset’ to remove a commit). You +can verify that the loose objects are gone by looking at the +‘.git/objects’ directory or by running + + $ git count-objects + 0 objects, 0 kilobytes + + Although the object files are gone, any commands that refer to those +objects will work exactly as they did before. + + The git-gc(1) (git-gc.html) command performs packing, pruning, and +more for you, so is normally the only high-level command you need. + + +File: git.info, Node: Dangling objects, Next: Recovering from repository corruption, Prev: How Git stores objects efficiently; pack files, Up: The Object Database + +7.1.7 Dangling objects +---------------------- + +The git-fsck(1) (git-fsck.html) command will sometimes complain about +dangling objects. They are not a problem. + + The most common cause of dangling objects is that you’ve rebased a +branch, or you have pulled from somebody else who rebased a branch—see +*note Rewriting history and maintaining patch series::. In that case, +the old head of the original branch still exists, as does everything it +pointed to. The branch pointer itself just doesn’t, since you replaced +it with another one. + + There are also other situations that cause dangling objects. For +example, a "dangling blob" may arise because you did a ‘git add’ of a +file, but then, before you actually committed it and made it part of the +bigger picture, you changed something else in that file and committed +that *updated* thing—the old state that you added originally ends up not +being pointed to by any commit or tree, so it’s now a dangling blob +object. + + Similarly, when the "recursive" merge strategy runs, and finds that +there are criss-cross merges and thus more than one merge base (which is +fairly unusual, but it does happen), it will generate one temporary +midway tree (or possibly even more, if you had lots of criss-crossing +merges and more than two merge bases) as a temporary internal merge +base, and again, those are real objects, but the end result will not end +up pointing to them, so they end up "dangling" in your repository. + + Generally, dangling objects aren’t anything to worry about. They can +even be very useful: if you screw something up, the dangling objects can +be how you recover your old tree (say, you did a rebase, and realized +that you really didn’t want to—you can look at what dangling objects you +have, and decide to reset your head to some old dangling state). + + For commits, you can just use: + + $ gitk <dangling-commit-sha-goes-here> --not --all + + This asks for all the history reachable from the given commit but not +from any branch, tag, or other reference. If you decide it’s something +you want, you can always create a new reference to it, e.g., + + $ git branch recovered-branch <dangling-commit-sha-goes-here> + + For blobs and trees, you can’t do the same, but you can still examine +them. You can just do + + $ git show <dangling-blob/tree-sha-goes-here> + + to show what the contents of the blob were (or, for a tree, basically +what the ‘ls’ for that directory was), and that may give you some idea +of what the operation was that left that dangling object. + + Usually, dangling blobs and trees aren’t very interesting. They’re +almost always the result of either being a half-way mergebase (the blob +will often even have the conflict markers from a merge in it, if you +have had conflicting merges that you fixed up by hand), or simply +because you interrupted a ‘git fetch’ with ^C or something like that, +leaving _some_ of the new objects in the object database, but just +dangling and useless. + + Anyway, once you are sure that you’re not interested in any dangling +state, you can just prune all unreachable objects: + + $ git prune + + and they’ll be gone. (You should only run ‘git prune’ on a quiescent +repository—it’s kind of like doing a filesystem fsck recovery: you don’t +want to do that while the filesystem is mounted. ‘git prune’ is +designed not to cause any harm in such cases of concurrent accesses to a +repository but you might receive confusing or scary messages.) + + +File: git.info, Node: Recovering from repository corruption, Prev: Dangling objects, Up: The Object Database + +7.1.8 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 solvable 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) (git-fsck.html); this may be +time-consuming. + + Assume the output looks like this: + + $ git fsck --full --no-dangling + broken link from tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8 + to blob 4b9458b3786228369c63936db65827de3cc06200 + missing blob 4b9458b3786228369c63936db65827de3cc06200 + + 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) +(git-ls-tree.html), 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.html): + + $ git hash-object -w somedirectory/myfile + + which will create and store a blob object with the contents of +somedirectory/myfile, and output the SHA-1 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 following version of the file was +"newsha", and that the immediately preceding 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. + + +File: git.info, Node: The index, Prev: The Object Database, Up: Git concepts + +7.2 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 SHA-1 of a blob +object; git-ls-files(1) (git-ls-files.html) can show you the contents of +the index: + + $ git ls-files --stage + 100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0 .gitignore + 100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0 .mailmap + 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0 COPYING + 100644 a37b2152bd26be2c2289e1f57a292534a51a93c7 0 Documentation/.gitignore + 100644 fbefe9a45b00a54b58d94d06eca48b03d40a50e0 0 Documentation/Makefile + ... + 100644 2511aef8d89ab52be5ec6a5e46236b4b6bcd07ea 0 xdiff/xtypes.h + 100644 2ade97b2574a9f77e7ae4002a4e07a6a38e46d07 0 xdiff/xutils.c + 100644 d5de8292e05e7c36c4b68857c1cf9855e3d2f70a 0 xdiff/xutils.h + + Note that in older documentation you may see the index called the +"current directory cache" or just the "cache". It has three important +properties: + + 1. The index contains all the information necessary to generate a + single (uniquely determined) tree object. + + For example, running git-commit(1) (git-commit.html) generates this + tree object from the index, stores it in the object database, and + uses it as the tree object associated with the new commit. + + 2. The index enables fast comparisons between the tree object it + defines and the working tree. + + It does this by storing some additional data for each entry (such + as the last modified time). This data is not displayed above, and + is not stored in the created tree object, but it can be used to + determine quickly which files in the working directory differ from + what was stored in the index, and thus save Git from having to read + all of the data from such files to look for changes. + + 3. It can efficiently represent information about merge conflicts + between different tree objects, allowing each pathname to be + associated with sufficient information about the trees involved + that you can create a three-way merge between them. + + We saw in *note Getting conflict-resolution help during a merge:: + that during a merge the index can store multiple versions of a + single file (called "stages"). The third column in the + git-ls-files(1) (git-ls-files.html) output above is the stage + 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. + + +File: git.info, Node: Submodules, Next: Low-level Git operations, Prev: Git concepts, Up: Top + +8 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 decompression library; several independent +programs might all share the same build scripts. + + With centralized revision control systems this is often accomplished +by including every module in one single repository. Developers can +check out all modules or only the modules they need to work with. They +can even modify files across several modules in a single commit while +moving things around or updating APIs and translations. + + Git does not allow partial checkouts, so duplicating this approach in +Git would force developers to keep a local copy of modules they are not +interested in touching. Commits in an enormous checkout would be slower +than you’d expect as Git would have to scan every directory for changes. +If modules have a lot of local history, clones would take forever. + + On the plus side, distributed revision control systems can much +better integrate with external sources. In a centralized model, a +single arbitrary snapshot of the external project is exported from its +own revision control and then imported into the local revision control +on a vendor branch. All the history is hidden. With distributed +revision control you can clone the entire external history and much more +easily follow development and re-merge local changes. + + Git’s submodule support allows a repository to contain, as a +subdirectory, a checkout of an external project. Submodules maintain +their own identity; the submodule support just stores the submodule +repository location and commit ID, so other developers who clone the +containing project ("superproject") can easily clone all the submodules +at the same revision. Partial checkouts of the superproject are +possible: you can tell Git to clone none, some or all of the submodules. + + The git-submodule(1) (git-submodule.html) command is available since +Git 1.5.3. Users with Git 1.5.2 can look up the submodule commits in +the repository and manually check them out; earlier versions won’t +recognize the submodules at all. + + To see how submodule support works, create four example repositories +that can be used later as a submodule: + + $ mkdir ~/git + $ cd ~/git + $ for i in a b c d + do + mkdir $i + cd $i + git init + echo "module $i" > $i.txt + git add $i.txt + git commit -m "Initial commit, submodule $i" + cd .. + done + + Now create the superproject and add all the submodules: + + $ mkdir super + $ cd super + $ git init + $ for i in a b c d + do + git submodule add ~/git/$i $i + done + + *Note* + + Do not use local URLs here if you plan to publish your + superproject! + + See what files ‘git submodule’ created: + + $ ls -a + . .. .git .gitmodules a b c d + + The ‘git submodule add <repo> <path>’ command does a couple of +things: + + • It clones the submodule from ‘<repo>’ to the given ‘<path>’ under + the current directory and by default checks out the master branch. + + • It adds the submodule’s clone path to the gitmodules(5) + (gitmodules.html) file and adds this file to the index, ready to be + committed. + + • It adds the submodule’s current commit ID to the index, ready to be + committed. + + Commit the superproject: + + $ git commit -m "Add submodules a, b, c and d." + + Now clone the superproject: + + $ cd .. + $ git clone super cloned + $ cd cloned + + The submodule directories are there, but they’re empty: + + $ ls -a a + . .. + $ git submodule status + -d266b9873ad50488163457f025db7cdd9683d88b a + -e81d457da15309b4fef4249aba9b50187999670d b + -c1536a972b9affea0f16e0680ba87332dc059146 c + -d96249ff5d57de5de093e6baff9e0aafa5276a74 d + + *Note* + + The commit object names shown above would be different for you, but + they should match the HEAD commit object names of your + repositories. You can check it by running ‘git ls-remote ../a’. + + Pulling down the submodules is a two-step process. First run ‘git +submodule init’ to add the submodule repository URLs to ‘.git/config’: + + $ git submodule init + + Now use ‘git submodule update’ to clone the repositories and check +out the commits specified in the superproject: + + $ git submodule update + $ cd a + $ ls -a + . .. .git a.txt + + One major difference between ‘git submodule update’ and ‘git +submodule add’ is that ‘git submodule update’ checks out a specific +commit, rather than the tip of a branch. It’s like checking out a tag: +the head is detached, so you’re not working on a branch. + + $ git branch + * (detached from d266b98) + master + + If you want to make a change within a submodule and you have a +detached head, then you should create or checkout a branch, make your +changes, publish the change within the submodule, and then update the +superproject to reference the new commit: + + $ git switch master + + or + + $ git switch -c fix-up + + then + + $ echo "adding a line again" >> a.txt + $ git commit -a -m "Updated the submodule from within the superproject." + $ git push + $ cd .. + $ git diff + diff --git a/a b/a + index d266b98..261dfac 160000 + --- a/a + +++ b/a + @@ -1 +1 @@ + -Subproject commit d266b9873ad50488163457f025db7cdd9683d88b + +Subproject commit 261dfac35cb99d380eb966e102c1197139f7fa24 + $ 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. + +* Menu: + +* Pitfalls with submodules:: + + +File: git.info, Node: Pitfalls with submodules, Up: Submodules + +8.1 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 + $ git commit -a -m "doing it wrong this time" + $ cd .. + $ git add a + $ git commit -m "Updated submodule a again." + $ git push + $ cd ~/git/cloned + $ git pull + $ git submodule update + error: pathspec '261dfac35cb99d380eb966e102c1197139f7fa24' did not match any file(s) known to git. + Did you forget to 'git add'? + Unable to checkout '261dfac35cb99d380eb966e102c1197139f7fa24' in submodule path 'a' + + In older Git versions it could be easily forgotten to commit new or +modified files in a submodule, which silently leads to similar problems +as not pushing the submodule changes. Starting with Git 1.7.0 both ‘git +status’ and ‘git diff’ in the superproject show submodules as modified +when they contain new or modified files to protect against accidentally +committing such a state. ‘git diff’ will also add a ‘-dirty’ to the +work tree side when generating patch output or used with the +‘--submodule’ option: + + $ git diff + diff --git a/sub b/sub + --- a/sub + +++ b/sub + @@ -1 +1 @@ + -Subproject commit 3f356705649b5d566d97ff843cf193359229a453 + +Subproject commit 3f356705649b5d566d97ff843cf193359229a453-dirty + $ git diff --submodule + Submodule sub 3f35670..3f35670-dirty: + + You also should not rewind branches in a submodule beyond commits +that were ever recorded in any superproject. + + It’s not safe to run ‘git submodule update’ if you’ve made and +committed changes within a submodule without checking out a branch +first. They will be silently overwritten: + + $ cat a.txt + module a + $ echo line added from private2 >> a.txt + $ git commit -a -m "line added inside private2" + $ cd .. + $ git submodule update + Submodule path 'a': checked out 'd266b9873ad50488163457f025db7cdd9683d88b' + $ cd a + $ cat a.txt + module a + + *Note* + + The changes are still visible in the submodule’s reflog. + + If you have uncommitted changes in your submodule working tree, ‘git +submodule update’ will not overwrite them. Instead, you get the usual +warning about not being able switch from a dirty branch. + + +File: git.info, Node: Low-level Git operations, Next: Hacking Git, Prev: Submodules, Up: Top + +9 Low-level Git operations +************************** + +Many of the higher-level commands were originally implemented as shell +scripts using a smaller core of low-level Git commands. These can still +be useful when doing unusual things with Git, or just as a way to +understand its inner workings. + +* Menu: + +* Object access and manipulation:: +* The Workflow:: +* Examining the data:: +* Merging multiple trees:: +* Merging multiple trees, continued: Merging multiple trees; continued. + + +File: git.info, Node: Object access and manipulation, Next: The Workflow, Up: Low-level Git operations + +9.1 Object access and manipulation +================================== + +The git-cat-file(1) (git-cat-file.html) command can show the contents of +any object, though the higher-level git-show(1) (git-show.html) is +usually more useful. + + The git-commit-tree(1) (git-commit-tree.html) command allows +constructing commits with arbitrary parents and trees. + + A tree can be created with git-write-tree(1) (git-write-tree.html) +and its data can be accessed by git-ls-tree(1) (git-ls-tree.html). Two +trees can be compared with git-diff-tree(1) (git-diff-tree.html). + + A tag is created with git-mktag(1) (git-mktag.html), and the +signature can be verified by git-verify-tag(1) (git-verify-tag.html), +though it is normally simpler to use git-tag(1) (git-tag.html) for both. + + +File: git.info, Node: The Workflow, Next: Examining the data, Prev: Object access and manipulation, Up: Low-level Git operations + +9.2 The Workflow +================ + +High-level operations such as git-commit(1) (git-commit.html) and +git-restore(1) (git-restore.html) work by moving data between the +working tree, the index, and the object database. Git provides +low-level operations which perform each of these steps individually. + + Generally, all Git operations work on the index file. Some +operations work *purely* on the index file (showing the current state of +the index), but most operations move data between the index file and +either the database or the working directory. Thus there are four main +combinations: + +* Menu: + +* working directory → index:: +* index → object database:: +* object database → index:: +* index → working directory:: +* Tying it all together:: + + +File: git.info, Node: working directory → index, Next: index → object database, Up: The Workflow + +9.2.1 working directory → index +------------------------------- + +The git-update-index(1) (git-update-index.html) command updates the +index with information from the working directory. You generally update +the index information by just specifying the filename you want to +update, like so: + + $ git update-index filename + + but to avoid common mistakes with filename globbing etc., the command +will not normally add totally new entries or remove old entries, i.e. +it will normally just update existing cache entries. + + To tell Git that yes, you really do realize that certain files no +longer exist, or that new files should be added, you should use the +‘--remove’ and ‘--add’ flags respectively. + + NOTE! A ‘--remove’ flag does _not_ mean that subsequent filenames +will necessarily be removed: if the files still exist in your directory +structure, the index will be updated with their new status, not removed. +The only thing ‘--remove’ means is that update-index will be considering +a removed file to be a valid thing, and if the file really does not +exist any more, it will update the index accordingly. + + As a special case, you can also do ‘git update-index --refresh’, +which will refresh the "stat" information of each index to match the +current stat information. It will _not_ update the object status +itself, and it will only update the fields that are used to quickly test +whether an object still matches its old backing store object. + + The previously introduced git-add(1) (git-add.html) is just a wrapper +for git-update-index(1) (git-update-index.html). + + +File: git.info, Node: index → object database, Next: object database → index, Prev: working directory → index, Up: The Workflow + +9.2.2 index → object database +----------------------------- + +You write your current index file to a "tree" object with the program + + $ git write-tree + + that doesn’t come with any options—it will just write out the current +index into the set of tree objects that describe that state, and it will +return the name of the resulting top-level tree. You can use that tree +to re-generate the index at any time by going in the other direction: + + +File: git.info, Node: object database → index, Next: index → working directory, Prev: index → object database, Up: The Workflow + +9.2.3 object database → index +----------------------------- + +You read a "tree" file from the object database, and use that to +populate (and overwrite—don’t do this if your index contains any unsaved +state that you might want to restore later!) your current index. +Normal operation is just + + $ git read-tree <SHA-1 of tree> + + and your index file will now be equivalent to the tree that you saved +earlier. However, that is only your _index_ file: your working +directory contents have not been modified. + + +File: git.info, Node: index → working directory, Next: Tying it all together, Prev: object database → index, Up: The Workflow + +9.2.4 index → working directory +------------------------------- + +You update your working directory from the index by "checking out" +files. This is not a very common operation, since normally you’d just +keep your files updated, and rather than write to your working +directory, you’d tell the index files about the changes in your working +directory (i.e. ‘git update-index’). + + However, if you decide to jump to a new version, or check out +somebody else’s version, or just restore a previous tree, you’d populate +your index file with read-tree, and then you need to check out the +result with + + $ git checkout-index filename + + or, if you want to check out all of the index, use ‘-a’. + + NOTE! ‘git checkout-index’ normally refuses to overwrite old files, +so if you have an old version of the tree already checked out, you will +need to use the ‘-f’ flag (_before_ the ‘-a’ flag or the filename) to +_force_ the checkout. + + Finally, there are a few odds and ends which are not purely moving +from one representation to the other: + + +File: git.info, Node: Tying it all together, Prev: index → working directory, Up: The Workflow + +9.2.5 Tying it all together +--------------------------- + +To commit a tree you have instantiated with ‘git write-tree’, you’d +create a "commit" object that refers to that tree and the history behind +it—most notably the "parent" commits that preceded it in history. + + Normally a "commit" has one parent: the previous state of the tree +before a certain change was made. However, sometimes it can have two or +more parent commits, in which case we call it a "merge", due to the fact +that such a commit brings together ("merges") two or more previous +states represented by other commits. + + In other words, while a "tree" represents a particular directory +state of a working directory, a "commit" represents that state in time, +and explains how we got there. + + You create a commit object by giving it the tree that describes the +state at the time of the commit, and a list of parents: + + $ git commit-tree <tree> -p <parent> [(-p <parent2>)...] + + and then giving the reason for the commit on stdin (either through +redirection from a pipe or file, or by just typing it at the tty). + + ‘git commit-tree’ will return the name of the object that represents +that commit, and you should save it away for later use. Normally, you’d +commit a new ‘HEAD’ state, and while Git doesn’t care where you save the +note about that state, in practice we tend to just write the result to +the file pointed at by ‘.git/HEAD’, so that we can always see what the +last committed state was. + + Here is a picture that illustrates how various pieces fit together: + + commit-tree + commit obj + +----+ + | | + | | + V V + +-----------+ + | Object DB | + | Backing | + | Store | + +-----------+ + ^ + write-tree | | + tree obj | | + | | read-tree + | | tree obj + V + +-----------+ + | Index | + | "cache" | + +-----------+ + update-index ^ + blob obj | | + | | + checkout-index -u | | checkout-index + stat | | blob obj + V + +-----------+ + | Working | + | Directory | + +-----------+ + + +File: git.info, Node: Examining the data, Next: Merging multiple trees, Prev: The Workflow, Up: Low-level Git operations + +9.3 Examining the data +====================== + +You can examine the data represented in the object database and the +index with various helper tools. For every object, you can use +git-cat-file(1) (git-cat-file.html) to examine details about the object: + + $ git cat-file -t <objectname> + + shows the type of the object, and once you have the type (which is +usually implicit in where you find the object), you can use + + $ git cat-file blob|tree|commit|tag <objectname> + + to show its contents. NOTE! Trees have binary content, and as a +result there is a special helper for showing that content, called ‘git +ls-tree’, which turns the binary content into a more easily readable +form. + + It’s especially instructive to look at "commit" objects, since those +tend to be small and fairly self-explanatory. In particular, if you +follow the convention of having the top commit name in ‘.git/HEAD’, you +can do + + $ git cat-file commit HEAD + + to see what the top commit was. + + +File: git.info, Node: Merging multiple trees, Next: Merging multiple trees; continued, Prev: Examining the data, Up: Low-level Git operations + +9.4 Merging multiple trees +========================== + +Git can help you perform a three-way merge, which can in turn be used +for a many-way merge by repeating the merge procedure several times. +The usual situation is that you only do one three-way merge (reconciling +two lines of history) and commit the result, but if you like to, you can +merge several branches in one go. + + To perform a three-way merge, you start with the two commits you want +to merge, find their closest common parent (a third commit), and compare +the trees corresponding to these three commits. + + To get the "base" for the merge, look up the common parent of two +commits: + + $ git merge-base <commit1> <commit2> + + This prints the name of a commit they are both based on. You should +now look up the tree objects of those commits, which you can easily do +with + + $ git cat-file commit <commitname> | head -1 + + since the tree object information is always the first line in a +commit object. + + Once you know the three trees you are going to merge (the one +"original" tree, aka the common tree, and the two "result" trees, aka +the branches you want to merge), you do a "merge" read into the index. +This will complain if it has to throw away your old index contents, so +you should make sure that you’ve committed those—in fact you would +normally always do a merge against your last commit (which should thus +match what you have in your current index anyway). + + To do the merge, do + + $ git read-tree -m -u <origtree> <yourtree> <targettree> + + which will do all trivial merge operations for you directly in the +index file, and you can just write the result out with ‘git write-tree’. + + +File: git.info, Node: Merging multiple trees; continued, Prev: Merging multiple trees, Up: Low-level Git operations + +9.5 Merging multiple trees, continued +===================================== + +Sadly, many merges aren’t trivial. If there are files that have been +added, moved or removed, or if both branches have modified the same +file, you will be left with an index tree that contains "merge entries" +in it. Such an index tree can _NOT_ be written out to a tree object, +and you will have to resolve any such merge clashes using other tools +before you can write out the result. + + You can examine such index state with ‘git ls-files --unmerged’ +command. An example: + + $ git read-tree -m $orig HEAD $target + $ git ls-files --unmerged + 100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello.c + 100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello.c + 100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello.c + + Each line of the ‘git ls-files --unmerged’ output begins with the +blob mode bits, blob SHA-1, _stage number_, and the filename. The +_stage number_ is Git’s way to say which tree it came from: stage 1 +corresponds to the ‘$orig’ tree, stage 2 to the ‘HEAD’ tree, and stage 3 +to the ‘$target’ tree. + + Earlier we said that trivial merges are done inside ‘git read-tree +-m’. For example, if the file did not change from ‘$orig’ to ‘HEAD’ or +‘$target’, or if the file changed from ‘$orig’ to ‘HEAD’ and ‘$orig’ to +‘$target’ the same way, obviously the final outcome is what is in +‘HEAD’. What the above example shows is that file ‘hello.c’ was changed +from ‘$orig’ to ‘HEAD’ and ‘$orig’ to ‘$target’ in a different way. You +could resolve this by running your favorite 3-way merge program, e.g. +‘diff3’, ‘merge’, or Git’s own merge-file, on the blob objects from +these three stages yourself, like this: + + $ git cat-file blob 263414f >hello.c~1 + $ git cat-file blob 06fa6a2 >hello.c~2 + $ git cat-file blob cc44c73 >hello.c~3 + $ git merge-file hello.c~2 hello.c~1 hello.c~3 + + This would leave the merge result in ‘hello.c~2’ file, along with +conflict markers if there are conflicts. After verifying the merge +result makes sense, you can tell Git what the final merge result for +this file is by: + + $ mv -f hello.c~2 hello.c + $ git update-index hello.c + + When a path is in the "unmerged" state, running ‘git update-index’ +for that path tells Git to mark the path resolved. + + The above is the description of a Git merge at the lowest level, to +help you understand what conceptually happens under the hood. In +practice, nobody, not even Git itself, runs ‘git cat-file’ three times +for this. There is a ‘git merge-index’ program that extracts the stages +to temporary files and calls a "merge" script on it: + + $ git merge-index git-merge-one-file hello.c + + and that is what higher level ‘git merge -s resolve’ is implemented +with. + + +File: git.info, Node: Hacking Git, Next: Git Glossary, Prev: Low-level Git operations, Up: Top + +10 Hacking Git +************** + +This chapter covers internal details of the Git implementation which +probably only Git developers need to understand. + +* Menu: + +* Object storage format:: +* A birds-eye view of Git’s source code:: + + +File: git.info, Node: Object storage format, Next: A birds-eye view of Git’s source code, Up: Hacking Git + +10.1 Object storage format +========================== + +All objects have a statically determined "type" which identifies the +format of the object (i.e. how it is used, and how it can refer to +other objects). There are currently four different object types: +"blob", "tree", "commit", and "tag". + + Regardless of object type, all objects share the following +characteristics: they are all deflated with zlib, and have a header that +not only specifies their type, but also provides size information about +the data in the object. It’s worth noting that the SHA-1 hash that is +used to name the object is the hash of the original data plus this +header, so ‘sha1sum’ _file_ does not match the object name for _file_. + + As a result, the general consistency of an object can always be +tested independently of the contents or the type of the object: all +objects can be validated by verifying that (a) their hashes match the +content of the file and (b) the object successfully inflates to a stream +of bytes that forms a sequence of ‘<ascii type without space> + <space> ++ <ascii decimal size> + <byte\0> + <binary object data>’. + + The structured objects can further have their structure and +connectivity to other objects verified. This is generally done with the +‘git fsck’ program, which generates a full dependency graph of all +objects, and verifies their internal consistency (in addition to just +verifying their superficial consistency through the hash). + + +File: git.info, Node: A birds-eye view of Git’s source code, Prev: Object storage format, Up: Hacking Git + +10.2 A birds-eye view of Git’s source code +========================================== + +It is not always easy for new developers to find their way through Git’s +source code. This section gives you a little guidance to show where to +start. + + A good place to start is with the contents of the initial commit, +with: + + $ git switch --detach e83c5163 + + The initial revision lays the foundation for almost everything Git +has today, but is small enough to read in one sitting. + + Note that terminology has changed since that revision. For example, +the README in that revision uses the word "changeset" to describe what +we now call a commit (*note [def_commit_object]::). + + Also, we do not call it "cache" any more, but rather "index"; +however, the file is still called ‘cache.h’. Remark: Not much reason to +change it now, especially since there is no good single name for it +anyway, because it is basically _the_ header file which is included by +_all_ of Git’s C sources. + + If you grasp the ideas in that initial commit, you should check out a +more recent version and skim ‘cache.h’, ‘object.h’ and ‘commit.h’. + + In the early days, Git (in the tradition of UNIX) was a bunch of +programs which were extremely simple, and which you used in scripts, +piping the output of one into another. This turned out to be good for +initial development, since it was easier to test new things. However, +recently many of these parts have become builtins, and some of the core +has been "libified", i.e. put into libgit.a for performance, +portability reasons, and to avoid code duplication. + + By now, you know what the index is (and find the corresponding data +structures in ‘cache.h’), and that there are just a couple of object +types (blobs, trees, commits and tags) which inherit their common +structure from ‘struct object’, which is their first member (and thus, +you can cast e.g. ‘(struct object *)commit’ to achieve the _same_ as +‘&commit->object’, i.e. get at the object name and flags). + + Now is a good point to take a break to let this information sink in. + + Next step: get familiar with the object naming. Read *note Naming +commits::. There are quite a few ways to name an object (and not only +revisions!). All of these are handled in ‘sha1_name.c’. Just have a +quick look at the function ‘get_sha1()’. A lot of the special handling +is done by functions like ‘get_sha1_basic()’ or the likes. + + This is just to get you into the groove for the most libified part of +Git: the revision walker. + + Basically, the initial version of ‘git log’ was a shell script: + + $ git-rev-list --pretty $(git-rev-parse --default HEAD "$@") | \ + LESS=-S ${PAGER:-less} + + What does this mean? + + ‘git rev-list’ is the original version of the revision walker, which +_always_ printed a list of revisions to stdout. It is still functional, +and needs to, since most new Git commands start out as scripts using +‘git rev-list’. + + ‘git rev-parse’ is not as important any more; it was only used to +filter out options that were relevant for the different plumbing +commands that were called by the script. + + Most of what ‘git rev-list’ did is contained in ‘revision.c’ and +‘revision.h’. It wraps the options in a struct named ‘rev_info’, which +controls how and what revisions are walked, and more. + + The original job of ‘git rev-parse’ is now taken by the function +‘setup_revisions()’, which parses the revisions and the common +command-line options for the revision walker. This information is +stored in the struct ‘rev_info’ for later consumption. You can do your +own command-line option parsing after calling ‘setup_revisions()’. +After that, you have to call ‘prepare_revision_walk()’ for +initialization, and then you can get the commits one by one with the +function ‘get_revision()’. + + If you are interested in more details of the revision walking +process, just have a look at the first implementation of ‘cmd_log()’; +call ‘git show v1.3.0~155^2~4’ and scroll down to that function (note +that you no longer need to call ‘setup_pager()’ directly). + + Nowadays, ‘git log’ is a builtin, which means that it is _contained_ +in the command ‘git’. The source side of a builtin is + + • a function called ‘cmd_<bla>’, typically defined in + ‘builtin/<bla.c>’ (note that older versions of Git used to have it + in ‘builtin-<bla>.c’ instead), and declared in ‘builtin.h’. + + • an entry in the ‘commands[]’ array in ‘git.c’, and + + • an entry in ‘BUILTIN_OBJECTS’ in the ‘Makefile’. + + Sometimes, more than one builtin is contained in one source file. +For example, ‘cmd_whatchanged()’ and ‘cmd_log()’ both reside in +‘builtin/log.c’, since they share quite a bit of code. In that case, +the commands which are _not_ named like the ‘.c’ file in which they live +have to be listed in ‘BUILT_INS’ in the ‘Makefile’. + + ‘git log’ looks more complicated in C than it does in the original +script, but that allows for a much greater flexibility and performance. + + Here again it is a good point to take a pause. + + Lesson three is: study the code. Really, it is the best way to learn +about the organization of Git (after you know the basic concepts). + + So, think about something which you are interested in, say, "how can +I access a blob just knowing the object name of it?". The first step is +to find a Git command with which you can do it. In this example, it is +either ‘git show’ or ‘git cat-file’. + + For the sake of clarity, let’s stay with ‘git cat-file’, because it + + • is plumbing, and + + • was around even in the initial commit (it literally went only + through some 20 revisions as ‘cat-file.c’, was renamed to + ‘builtin/cat-file.c’ when made a builtin, and then saw less than 10 + versions). + + So, look into ‘builtin/cat-file.c’, search for ‘cmd_cat_file()’ and +look what it does. + + git_config(git_default_config); + if (argc != 3) + usage("git cat-file [-t|-s|-e|-p|<type>] <sha1>"); + if (get_sha1(argv[2], sha1)) + die("Not a valid object name %s", argv[2]); + + Let’s skip over the obvious details; the only really interesting part +here is the call to ‘get_sha1()’. It tries to interpret ‘argv[2]’ as an +object name, and if it refers to an object which is present in the +current repository, it writes the resulting SHA-1 into the variable +‘sha1’. + + Two things are interesting here: + + • ‘get_sha1()’ returns 0 on _success_. This might surprise some new + Git hackers, but there is a long tradition in UNIX to return + different negative numbers in case of different errors—and 0 on + success. + + • the variable ‘sha1’ in the function signature of ‘get_sha1()’ is + ‘unsigned char *’, but is actually expected to be a pointer to + ‘unsigned char[20]’. This variable will contain the 160-bit SHA-1 + of the given commit. Note that whenever a SHA-1 is passed as + ‘unsigned char *’, it is the binary representation, as opposed to + the ASCII representation in hex characters, which is passed as + ‘char *’. + + You will see both of these things throughout the code. + + Now, for the meat: + + case 0: + buf = read_object_with_reference(sha1, argv[1], &size, NULL); + + This is how you read a blob (actually, not only a blob, but any type +of object). To know how the function ‘read_object_with_reference()’ +actually works, find the source code for it (something like ‘git grep +read_object_with | grep ":[a-z]"’ in the Git repository), and read the +source. + + To find out how the result can be used, just read on in +‘cmd_cat_file()’: + + write_or_die(1, buf, size); + + Sometimes, you do not know where to look for a feature. In many such +cases, it helps to search through the output of ‘git log’, and then ‘git +show’ the corresponding commit. + + Example: If you know that there was some test case for ‘git bundle’, +but do not remember where it was (yes, you _could_ ‘git grep bundle t/’, +but that does not illustrate the point!): + + $ git log --no-merges t/ + + In the pager (‘less’), just search for "bundle", go a few lines back, +and see that it is in commit 18449ab0. Now just copy this object name, +and paste it into the command line + + $ git show 18449ab0 + + Voila. + + Another example: Find out what to do in order to make some script a +builtin: + + $ git log --no-merges --diff-filter=A builtin/*.c + + You see, Git is actually the best tool to find out about the source +of Git itself! + + +File: git.info, Node: Git Glossary, Next: Git Quick Reference, Prev: Hacking Git, Up: Top + +11 Git Glossary +*************** + +* Menu: + +* Git explained:: + + +File: git.info, Node: Git explained, Up: Git Glossary + +11.1 Git explained +================== + +alternate object database + Via the alternates mechanism, a repository (*note + [def_repository]::) can inherit part of its object database (*note + [def_object_database]::) from another object database, which is + called an "alternate". + +bare repository + A bare repository is normally an appropriately named directory + (*note [def_directory]::) with a ‘.git’ suffix that does not have a + locally checked-out copy of any of the files under revision + control. That is, all of the Git administrative and control files + that would normally be present in the hidden ‘.git’ sub-directory + are directly present in the ‘repository.git’ directory instead, and + no other files are present and checked out. Usually publishers of + public repositories make bare repositories available. + +blob object + Untyped object (*note [def_object]::), e.g. the contents of a + file. + +branch + A "branch" is a line of development. The most recent commit (*note + [def_commit]::) on a branch is referred to as the tip of that + branch. The tip of the branch is referenced by a branch head + (*note [def_head]::), which moves forward as additional development + is done on the branch. A single Git repository (*note + [def_repository]::) can track an arbitrary number of branches, but + your working tree (*note [def_working_tree]::) is associated with + just one of them (the "current" or "checked out" branch), and HEAD + (*note [def_HEAD]::) points to that branch. + +cache + Obsolete for: index (*note [def_index]::). + +chain + A list of objects, where each object (*note [def_object]::) in the + list contains a reference to its successor (for example, the + successor of a commit (*note [def_commit]::) could be one of its + parents (*note [def_parent]::)). + +changeset + BitKeeper/cvsps speak for "commit (*note [def_commit]::)". Since + Git does not store changes, but states, it really does not make + sense to use the term "changesets" with Git. + +checkout + The action of updating all or part of the working tree (*note + [def_working_tree]::) with a tree object (*note + [def_tree_object]::) or blob (*note [def_blob_object]::) from the + object database (*note [def_object_database]::), and updating the + index (*note [def_index]::) and HEAD (*note [def_HEAD]::) if the + whole working tree has been pointed at a new branch (*note + [def_branch]::). + +cherry-picking + In SCM (*note [def_SCM]::) jargon, "cherry pick" means to choose a + subset of changes out of a series of changes (typically commits) + and record them as a new series of changes on top of a different + codebase. In Git, this is performed by the "git cherry-pick" + command to extract the change introduced by an existing commit + (*note [def_commit]::) and to record it based on the tip of the + current branch (*note [def_branch]::) as a new commit. + +clean + A working tree (*note [def_working_tree]::) is clean, if it + corresponds to the revision (*note [def_revision]::) referenced by + the current head (*note [def_head]::). Also see "dirty (*note + [def_dirty]::)". + +commit + As a noun: A single point in the Git history; the entire history of + a project is represented as a set of interrelated commits. The + word "commit" is often used by Git in the same places other + revision control systems use the words "revision" or "version". + Also used as a short hand for commit object (*note + [def_commit_object]::). + + As a verb: The action of storing a new snapshot of the project’s + state in the Git history, by creating a new commit representing the + current state of the index (*note [def_index]::) and advancing HEAD + (*note [def_HEAD]::) to point at the new commit. + +commit object + An object (*note [def_object]::) which contains the information + about a particular revision (*note [def_revision]::), such as + parents (*note [def_parent]::), committer, author, date and the + tree object (*note [def_tree_object]::) which corresponds to the + top directory (*note [def_directory]::) of the stored revision. + +commit-ish (also committish) + A commit object (*note [def_commit_object]::) or an object (*note + [def_object]::) that can be recursively dereferenced to a commit + object. The following are all commit-ishes: a commit object, a tag + object (*note [def_tag_object]::) that points to a commit object, a + tag object that points to a tag object that points to a commit + object, etc. + +core Git + Fundamental data structures and utilities of Git. Exposes only + limited source code management tools. + +DAG + Directed acyclic graph. The commit objects (*note + [def_commit_object]::) form a directed acyclic graph, because they + have parents (directed), and the graph of commit objects is acyclic + (there is no chain (*note [def_chain]::) which begins and ends with + the same object (*note [def_object]::)). + +dangling object + An unreachable object (*note [def_unreachable_object]::) which is + not reachable (*note [def_reachable]::) even from other unreachable + objects; a dangling object has no references to it from any + reference or object (*note [def_object]::) in the repository (*note + [def_repository]::). + +detached HEAD + Normally the HEAD (*note [def_HEAD]::) stores the name of a branch + (*note [def_branch]::), and commands that operate on the history + HEAD represents operate on the history leading to the tip of the + branch the HEAD points at. However, Git also allows you to check + out (*note [def_checkout]::) an arbitrary commit (*note + [def_commit]::) that isn’t necessarily the tip of any particular + branch. The HEAD in such a state is called "detached". + + Note that commands that operate on the history of the current + branch (e.g. ‘git commit’ to build a new history on top of it) + still work while the HEAD is detached. They update the HEAD to + point at the tip of the updated history without affecting any + branch. Commands that update or inquire information _about_ the + current branch (e.g. ‘git branch --set-upstream-to’ that sets what + remote-tracking branch the current branch integrates with) + obviously do not work, as there is no (real) current branch to ask + about in this state. + +directory + The list you get with "ls" :-) + +dirty + A working tree (*note [def_working_tree]::) is said to be "dirty" + if it contains modifications which have not been committed (*note + [def_commit]::) to the current branch (*note [def_branch]::). + +evil merge + An evil merge is a merge (*note [def_merge]::) that introduces + changes that do not appear in any parent (*note [def_parent]::). + +fast-forward + A fast-forward is a special type of merge (*note [def_merge]::) + where you have a revision (*note [def_revision]::) and you are + "merging" another branch (*note [def_branch]::)’s changes that + happen to be a descendant of what you have. In such a case, you do + not make a new merge (*note [def_merge]::) commit (*note + [def_commit]::) but instead just update to his revision. This will + happen frequently on a remote-tracking branch (*note + [def_remote_tracking_branch]::) of a remote repository (*note + [def_repository]::). + +fetch + Fetching a branch (*note [def_branch]::) means to get the branch’s + head ref (*note [def_head_ref]::) from a remote repository (*note + [def_repository]::), to find out which objects are missing from the + local object database (*note [def_object_database]::), and to get + them, too. See also git-fetch(1) (git-fetch.html). + +file system + Linus Torvalds originally designed Git to be a user space file + system, i.e. the infrastructure to hold files and directories. + That ensured the efficiency and speed of Git. + +Git archive + Synonym for repository (*note [def_repository]::) (for arch + people). + +gitfile + A plain file ‘.git’ at the root of a working tree that points at + the directory that is the real repository. + +grafts + Grafts enables two otherwise different lines of development to be + joined together by recording fake ancestry information for commits. + This way you can make Git pretend the set of parents (*note + [def_parent]::) a commit (*note [def_commit]::) has is different + from what was recorded when the commit was created. Configured via + the ‘.git/info/grafts’ file. + + Note that the grafts mechanism is outdated and can lead to problems + transferring objects between repositories; see git-replace(1) + (git-replace.html) for a more flexible and robust system to do the + same thing. + +hash + In Git’s context, synonym for object name (*note + [def_object_name]::). + +head + A named reference (*note [def_ref]::) to the commit (*note + [def_commit]::) at the tip of a branch (*note [def_branch]::). + Heads are stored in a file in ‘$GIT_DIR/refs/heads/’ directory, + except when using packed refs. (See git-pack-refs(1) + (git-pack-refs.html).) + +HEAD + The current branch (*note [def_branch]::). In more detail: Your + working tree (*note [def_working_tree]::) is normally derived from + the state of the tree referred to by HEAD. HEAD is a reference to + one of the heads (*note [def_head]::) in your repository, except + when using a detached HEAD (*note [def_detached_HEAD]::), in which + case it directly references an arbitrary commit. + +head ref + A synonym for head (*note [def_head]::). + +hook + During the normal execution of several Git commands, call-outs are + made to optional scripts that allow a developer to add + functionality or checking. Typically, the hooks allow for a + command to be pre-verified and potentially aborted, and allow for a + post-notification after the operation is done. The hook scripts + are found in the ‘$GIT_DIR/hooks/’ directory, and are enabled by + simply removing the ‘.sample’ suffix from the filename. In earlier + versions of Git you had to make them executable. + +index + A collection of files with stat information, whose contents are + stored as objects. The index is a stored version of your working + tree (*note [def_working_tree]::). Truth be told, it can also + contain a second, and even a third version of a working tree, which + are used when merging (*note [def_merge]::). + +index entry + The information regarding a particular file, stored in the index + (*note [def_index]::). An index entry can be unmerged, if a merge + (*note [def_merge]::) was started, but not yet finished (i.e. if + the index contains multiple versions of that file). + +master + The default development branch (*note [def_branch]::). Whenever + you create a Git repository (*note [def_repository]::), a branch + named "master" is created, and becomes the active branch. In most + cases, this contains the local development, though that is purely + by convention and is not required. + +merge + As a verb: To bring the contents of another branch (*note + [def_branch]::) (possibly from an external repository (*note + [def_repository]::)) into the current branch. In the case where + the merged-in branch is from a different repository, this is done + by first fetching (*note [def_fetch]::) the remote branch and then + merging the result into the current branch. This combination of + fetch and merge operations is called a pull (*note [def_pull]::). + Merging is performed by an automatic process that identifies + changes made since the branches diverged, and then applies all + those changes together. In cases where changes conflict, manual + intervention may be required to complete the merge. + + As a noun: unless it is a fast-forward (*note + [def_fast_forward]::), a successful merge results in the creation + of a new commit (*note [def_commit]::) representing the result of + the merge, and having as parents (*note [def_parent]::) the tips of + the merged branches (*note [def_branch]::). This commit is + referred to as a "merge commit", or sometimes just a "merge". + +object + The unit of storage in Git. It is uniquely identified by the SHA-1 + (*note [def_SHA1]::) of its contents. Consequently, an object + cannot be changed. + +object database + Stores a set of "objects", and an individual object (*note + [def_object]::) is identified by its object name (*note + [def_object_name]::). The objects usually live in + ‘$GIT_DIR/objects/’. + +object identifier + Synonym for object name (*note [def_object_name]::). + +object name + The unique identifier of an object (*note [def_object]::). The + object name is usually represented by a 40 character hexadecimal + string. Also colloquially called SHA-1 (*note [def_SHA1]::). + +object type + One of the identifiers "commit (*note [def_commit_object]::)", + "tree (*note [def_tree_object]::)", "tag (*note + [def_tag_object]::)" or "blob (*note [def_blob_object]::)" + describing the type of an object (*note [def_object]::). + +octopus + To merge (*note [def_merge]::) more than two branches (*note + [def_branch]::). + +origin + The default upstream repository (*note [def_repository]::). Most + projects have at least one upstream project which they track. By + default _origin_ is used for that purpose. New upstream updates + will be fetched into remote-tracking branches (*note + [def_remote_tracking_branch]::) named + origin/name-of-upstream-branch, which you can see using ‘git branch + -r’. + +overlay + Only update and add files to the working directory, but don’t + delete them, similar to how _cp -R_ would update the contents in + the destination directory. This is the default mode in a checkout + (*note [def_checkout]::) when checking out files from the index + (*note [def_index]::) or a tree-ish (*note [def_tree-ish]::). In + contrast, no-overlay mode also deletes tracked files not present in + the source, similar to _rsync –delete_. + +pack + A set of objects which have been compressed into one file (to save + space or to transmit them efficiently). + +pack index + The list of identifiers, and other information, of the objects in a + pack (*note [def_pack]::), to assist in efficiently accessing the + contents of a pack. + +pathspec + Pattern used to limit paths in Git commands. + + Pathspecs are used on the command line of "git ls-files", "git + ls-tree", "git add", "git grep", "git diff", "git checkout", and + many other commands to limit the scope of operations to some subset + of the tree or worktree. See the documentation of each command for + whether paths are relative to the current directory or toplevel. + The pathspec syntax is as follows: + + • any path matches itself + + • the pathspec up to the last slash represents a directory + prefix. The scope of that pathspec is limited to that + subtree. + + • the rest of the pathspec is a pattern for the remainder of the + pathname. Paths relative to the directory prefix will be + matched against that pattern using fnmatch(3); in particular, + _*_ and _?_ _can_ match directory separators. + + For example, Documentation/*.jpg will match all .jpg files in the + Documentation subtree, including + Documentation/chapter_1/figure_1.jpg. + + A pathspec that begins with a colon ‘:’ has special meaning. In + the short form, the leading colon ‘:’ is followed by zero or more + "magic signature" letters (which optionally is terminated by + another colon ‘:’), and the remainder is the pattern to match + against the path. The "magic signature" consists of ASCII symbols + that are neither alphanumeric, glob, regex special characters nor + colon. The optional colon that terminates the "magic signature" + can be omitted if the pattern begins with a character that does not + belong to "magic signature" symbol set and is not a colon. + + In the long form, the leading colon ‘:’ is followed by an open + parenthesis ‘(’, a comma-separated list of zero or more "magic + words", and a close parentheses ‘)’, and the remainder is the + pattern to match against the path. + + A pathspec with only a colon means "there is no pathspec". This + form should not be combined with other pathspec. + + top + The magic word ‘top’ (magic signature: ‘/’) makes the pattern + match from the root of the working tree, even when you are + running the command from inside a subdirectory. + + literal + Wildcards in the pattern such as ‘*’ or ‘?’ are treated as + literal characters. + + icase + Case insensitive match. + + glob + Git treats the pattern as a shell glob suitable for + consumption by fnmatch(3) with the FNM_PATHNAME flag: + wildcards in the pattern will not match a / in the pathname. + For example, "Documentation/*.html" matches + "Documentation/git.html" but not "Documentation/ppc/ppc.html" + or "tools/perf/Documentation/perf.html". + + Two consecutive asterisks ("‘**’") in patterns matched against + full pathname may have special meaning: + + • A leading "‘**’" followed by a slash means match in all + directories. For example, "‘**/foo’" matches file or + directory "‘foo’" anywhere, the same as pattern "‘foo’". + "‘**/foo/bar’" matches file or directory "‘bar’" anywhere + that is directly under directory "‘foo’". + + • A trailing "‘/**’" matches everything inside. For + example, "‘abc/**’" matches all files inside directory + "abc", relative to the location of the ‘.gitignore’ file, + with infinite depth. + + • A slash followed by two consecutive asterisks then a + slash matches zero or more directories. For example, + "‘a/**/b’" matches "‘a/b’", "‘a/x/b’", "‘a/x/y/b’" and so + on. + + • Other consecutive asterisks are considered invalid. + + Glob magic is incompatible with literal magic. + + attr + After ‘attr:’ comes a space separated list of "attribute + requirements", all of which must be met in order for the path + to be considered a match; this is in addition to the usual + non-magic pathspec pattern matching. See gitattributes(5) + (gitattributes.html). + + Each of the attribute requirements for the path takes one of + these forms: + + • "‘ATTR’" requires that the attribute ‘ATTR’ be set. + + • "‘-ATTR’" requires that the attribute ‘ATTR’ be unset. + + • "‘ATTR=VALUE’" requires that the attribute ‘ATTR’ be set + to the string ‘VALUE’. + + • "‘!ATTR’" requires that the attribute ‘ATTR’ be + unspecified. + + Note that when matching against a tree object, attributes + are still obtained from working tree, not from the given + tree object. + + exclude + After a path matches any non-exclude pathspec, it will be run + through all exclude pathspecs (magic signature: ‘!’ or its + synonym ‘^’). If it matches, the path is ignored. When there + is no non-exclude pathspec, the exclusion is applied to the + result set as if invoked without any pathspec. + +parent + A commit object (*note [def_commit_object]::) contains a (possibly + empty) list of the logical predecessor(s) in the line of + development, i.e. its parents. + +pickaxe + The term pickaxe (*note [def_pickaxe]::) refers to an option to the + diffcore routines that help select changes that add or delete a + given text string. With the ‘--pickaxe-all’ option, it can be used + to view the full changeset (*note [def_changeset]::) that + introduced or removed, say, a particular line of text. See + git-diff(1) (git-diff.html). + +plumbing + Cute name for core Git (*note [def_core_git]::). + +porcelain + Cute name for programs and program suites depending on core Git + (*note [def_core_git]::), presenting a high level access to core + Git. Porcelains expose more of a SCM (*note [def_SCM]::) interface + than the plumbing (*note [def_plumbing]::). + +per-worktree ref + Refs that are per-worktree (*note [def_working_tree]::), rather + than global. This is presently only HEAD (*note [def_HEAD]::) and + any refs that start with ‘refs/bisect/’, but might later include + other unusual refs. + +pseudoref + Pseudorefs are a class of files under ‘$GIT_DIR’ which behave like + refs for the purposes of rev-parse, but which are treated specially + by git. Pseudorefs both have names that are all-caps, and always + start with a line consisting of a SHA-1 (*note [def_SHA1]::) + followed by whitespace. So, HEAD is not a pseudoref, because it is + sometimes a symbolic ref. They might optionally contain some + additional data. ‘MERGE_HEAD’ and ‘CHERRY_PICK_HEAD’ are examples. + Unlike per-worktree refs (*note [def_per_worktree_ref]::), these + files cannot be symbolic refs, and never have reflogs. They also + cannot be updated through the normal ref update machinery. + Instead, they are updated by directly writing to the files. + However, they can be read as if they were refs, so ‘git rev-parse + MERGE_HEAD’ will work. + +pull + Pulling a branch (*note [def_branch]::) means to fetch (*note + [def_fetch]::) it and merge (*note [def_merge]::) it. See also + git-pull(1) (git-pull.html). + +push + Pushing a branch (*note [def_branch]::) means to get the branch’s + head ref (*note [def_head_ref]::) from a remote repository (*note + [def_repository]::), find out if it is an ancestor to the branch’s + local head ref, and in that case, putting all objects, which are + reachable (*note [def_reachable]::) from the local head ref, and + which are missing from the remote repository, into the remote + object database (*note [def_object_database]::), and updating the + remote head ref. If the remote head (*note [def_head]::) is not an + ancestor to the local head, the push fails. + +reachable + All of the ancestors of a given commit (*note [def_commit]::) are + said to be "reachable" from that commit. More generally, one + object (*note [def_object]::) is reachable from another if we can + reach the one from the other by a chain (*note [def_chain]::) that + follows tags (*note [def_tag]::) to whatever they tag, commits + (*note [def_commit_object]::) to their parents or trees, and trees + (*note [def_tree_object]::) to the trees or blobs (*note + [def_blob_object]::) that they contain. + +rebase + To reapply a series of changes from a branch (*note [def_branch]::) + to a different base, and reset the head (*note [def_head]::) of + that branch to the result. + +ref + A name that begins with ‘refs/’ (e.g. ‘refs/heads/master’) that + points to an object name (*note [def_object_name]::) or another ref + (the latter is called a symbolic ref (*note [def_symref]::)). For + convenience, a ref can sometimes be abbreviated when used as an + argument to a Git command; see gitrevisions(7) (gitrevisions.html) + for details. Refs are stored in the repository (*note + [def_repository]::). + + The ref namespace is hierarchical. Different subhierarchies are + used for different purposes (e.g. the ‘refs/heads/’ hierarchy is + used to represent local branches). + + There are a few special-purpose refs that do not begin with + ‘refs/’. The most notable example is ‘HEAD’. + +reflog + A reflog shows the local "history" of a ref. In other words, it + can tell you what the 3rd last revision in _this_ repository was, + and what was the current state in _this_ repository, yesterday + 9:14pm. See git-reflog(1) (git-reflog.html) for details. + +refspec + A "refspec" is used by fetch (*note [def_fetch]::) and push (*note + [def_push]::) to describe the mapping between remote ref (*note + [def_ref]::) and local ref. + +remote repository + A repository (*note [def_repository]::) which is used to track the + same project but resides somewhere else. To communicate with + remotes, see fetch (*note [def_fetch]::) or push (*note + [def_push]::). + +remote-tracking branch + A ref (*note [def_ref]::) that is used to follow changes from + another repository (*note [def_repository]::). It typically looks + like _refs/remotes/foo/bar_ (indicating that it tracks a branch + named _bar_ in a remote named _foo_), and matches the + right-hand-side of a configured fetch refspec (*note + [def_refspec]::). A remote-tracking branch should not contain + direct modifications or have local commits made to it. + +repository + A collection of refs (*note [def_ref]::) together with an object + database (*note [def_object_database]::) containing all objects + which are reachable (*note [def_reachable]::) from the refs, + possibly accompanied by meta data from one or more porcelains + (*note [def_porcelain]::). A repository can share an object + database with other repositories via alternates mechanism (*note + [def_alternate_object_database]::). + +resolve + The action of fixing up manually what a failed automatic merge + (*note [def_merge]::) left behind. + +revision + Synonym for commit (*note [def_commit]::) (the noun). + +rewind + To throw away part of the development, i.e. to assign the head + (*note [def_head]::) to an earlier revision (*note + [def_revision]::). + +SCM + Source code management (tool). + +SHA-1 + "Secure Hash Algorithm 1"; a cryptographic hash function. In the + context of Git used as a synonym for object name (*note + [def_object_name]::). + +shallow clone + Mostly a synonym to shallow repository (*note + [def_shallow_repository]::) but the phrase makes it more explicit + that it was created by running ‘git clone --depth=...’ command. + +shallow repository + A shallow repository (*note [def_repository]::) has an incomplete + history some of whose commits (*note [def_commit]::) have parents + (*note [def_parent]::) cauterized away (in other words, Git is told + to pretend that these commits do not have the parents, even though + they are recorded in the commit object (*note + [def_commit_object]::)). This is sometimes useful when you are + interested only in the recent history of a project even though the + real history recorded in the upstream is much larger. A shallow + repository is created by giving the ‘--depth’ option to + git-clone(1) (git-clone.html), and its history can be later + deepened with git-fetch(1) (git-fetch.html). + +stash entry + An object (*note [def_object]::) used to temporarily store the + contents of a dirty (*note [def_dirty]::) working directory and the + index for future reuse. + +submodule + A repository (*note [def_repository]::) that holds the history of a + separate project inside another repository (the latter of which is + called superproject (*note [def_superproject]::)). + +superproject + A repository (*note [def_repository]::) that references + repositories of other projects in its working tree as submodules + (*note [def_submodule]::). The superproject knows about the names + of (but does not hold copies of) commit objects of the contained + submodules. + +symref + Symbolic reference: instead of containing the SHA-1 (*note + [def_SHA1]::) id itself, it is of the format _ref: refs/some/thing_ + and when referenced, it recursively dereferences to this reference. + _HEAD (*note [def_HEAD]::)_ is a prime example of a symref. + Symbolic references are manipulated with the git-symbolic-ref(1) + (git-symbolic-ref.html) command. + +tag + A ref (*note [def_ref]::) under ‘refs/tags/’ namespace that points + to an object of an arbitrary type (typically a tag points to either + a tag (*note [def_tag_object]::) or a commit object (*note + [def_commit_object]::)). In contrast to a head (*note + [def_head]::), a tag is not updated by the ‘commit’ command. A Git + tag has nothing to do with a Lisp tag (which would be called an + object type (*note [def_object_type]::) in Git’s context). A tag + is most typically used to mark a particular point in the commit + ancestry chain (*note [def_chain]::). + +tag object + An object (*note [def_object]::) containing a ref (*note + [def_ref]::) pointing to another object, which can contain a + message just like a commit object (*note [def_commit_object]::). + It can also contain a (PGP) signature, in which case it is called a + "signed tag object". + +topic branch + A regular Git branch (*note [def_branch]::) that is used by a + developer to identify a conceptual line of development. Since + branches are very easy and inexpensive, it is often desirable to + have several small branches that each contain very well defined + concepts or small incremental yet related changes. + +tree + Either a working tree (*note [def_working_tree]::), or a tree + object (*note [def_tree_object]::) together with the dependent blob + (*note [def_blob_object]::) and tree objects (i.e. a stored + representation of a working tree). + +tree object + An object (*note [def_object]::) containing a list of file names + and modes along with refs to the associated blob and/or tree + objects. A tree (*note [def_tree]::) is equivalent to a directory + (*note [def_directory]::). + +tree-ish (also treeish) + A tree object (*note [def_tree_object]::) or an object (*note + [def_object]::) that can be recursively dereferenced to a tree + object. Dereferencing a commit object (*note + [def_commit_object]::) yields the tree object corresponding to the + revision (*note [def_revision]::)’s top directory (*note + [def_directory]::). The following are all tree-ishes: a commit-ish + (*note [def_commit-ish]::), a tree object, a tag object (*note + [def_tag_object]::) that points to a tree object, a tag object that + points to a tag object that points to a tree object, etc. + +unmerged index + An index (*note [def_index]::) which contains unmerged index + entries (*note [def_index_entry]::). + +unreachable object + An object (*note [def_object]::) which is not reachable (*note + [def_reachable]::) from a branch (*note [def_branch]::), tag (*note + [def_tag]::), or any other reference. + +upstream branch + The default branch (*note [def_branch]::) that is merged into the + branch in question (or the branch in question is rebased onto). It + is configured via branch.<name>.remote and branch.<name>.merge. If + the upstream branch of _A_ is _origin/B_ sometimes we say "_A_ is + tracking _origin/B_". + +working tree + The tree of actual checked out files. The working tree normally + contains the contents of the HEAD (*note [def_HEAD]::) commit’s + tree, plus any local changes that you have made but not yet + committed. + + +File: git.info, Node: Git Quick Reference, Next: Notes and todo list for this manual, Prev: Git Glossary, Up: Top + +Appendix A Git Quick Reference +****************************** + +This is a quick summary of the major commands; the previous chapters +explain how these work in more detail. + +* Menu: + +* Creating a new repository: Creating a new repository <1>. +* Managing branches:: +* Exploring history:: +* Making changes:: +* Merging:: +* Sharing your changes:: +* Repository maintenance:: + + +File: git.info, Node: Creating a new repository <1>, Next: Managing branches, Up: Git Quick Reference + +A.1 Creating a new repository +============================= + +From a tarball: + + $ tar xzf project.tar.gz + $ cd project + $ git init + Initialized empty Git repository in .git/ + $ git add . + $ git commit + + From a remote repository: + + $ git clone git://example.com/pub/project.git + $ cd project + + +File: git.info, Node: Managing branches, Next: Exploring history, Prev: Creating a new repository <1>, Up: Git Quick Reference + +A.2 Managing branches +===================== + + $ git branch # list all local branches in this repo + $ git switch test # switch working directory to branch "test" + $ git branch new # create branch "new" starting at current HEAD + $ git branch -d new # delete branch "new" + + Instead of basing a new branch on current HEAD (the default), use: + + $ git branch new test # branch named "test" + $ git branch new v2.6.15 # tag named v2.6.15 + $ git branch new HEAD^ # commit before the most recent + $ git branch new HEAD^^ # commit before that + $ git branch new test~10 # ten commits before tip of branch "test" + + Create and switch to a new branch at the same time: + + $ git switch -c new v2.6.15 + + Update and examine branches from the repository you cloned from: + + $ git fetch # update + $ git branch -r # list + origin/master + origin/next + ... + $ git switch -c masterwork origin/master + + Fetch a branch from a different repository, and give it a new name in +your repository: + + $ git fetch git://example.com/project.git theirbranch:mybranch + $ git fetch git://example.com/project.git v2.6.15:mybranch + + Keep a list of repositories you work with regularly: + + $ git remote add example git://example.com/project.git + $ git remote # list remote repositories + example + origin + $ git remote show example # get details + * remote example + URL: git://example.com/project.git + Tracked remote branches + master + next + ... + $ git fetch example # update branches from example + $ git branch -r # list all remote branches + + +File: git.info, Node: Exploring history, Next: Making changes, Prev: Managing branches, Up: Git Quick Reference + +A.3 Exploring history +===================== + + $ gitk # visualize and browse history + $ git log # list all commits + $ git log src/ # ...modifying src/ + $ git log v2.6.15..v2.6.16 # ...in v2.6.16, not in v2.6.15 + $ git log master..test # ...in branch test, not in branch master + $ git log test..master # ...in branch master, but not in test + $ git log test...master # ...in one branch, not in both + $ git log -S'foo()' # ...where difference contain "foo()" + $ git log --since="2 weeks ago" + $ git log -p # show patches as well + $ git show # most recent commit + $ git diff v2.6.15..v2.6.16 # diff between two tagged versions + $ git diff v2.6.15..HEAD # diff with current head + $ git grep "foo()" # search working directory for "foo()" + $ git grep v2.6.15 "foo()" # search old tree for "foo()" + $ git show v2.6.15:a.txt # look at old version of a.txt + + Search for regressions: + + $ git bisect start + $ git bisect bad # current version is bad + $ git bisect good v2.6.13-rc2 # last known good revision + Bisecting: 675 revisions left to test after this + # test here, then: + $ git bisect good # if this revision is good, or + $ git bisect bad # if this revision is bad. + # repeat until done. + + +File: git.info, Node: Making changes, Next: Merging, Prev: Exploring history, Up: Git Quick Reference + +A.4 Making changes +================== + +Make sure Git knows who to blame: + + $ cat >>~/.gitconfig <<\EOF + [user] + name = Your Name Comes Here + email = you@yourdomain.example.com + EOF + + Select file contents to include in the next commit, then make the +commit: + + $ git add a.txt # updated file + $ git add b.txt # new file + $ git rm c.txt # old file + $ git commit + + Or, prepare and create the commit in one step: + + $ git commit d.txt # use latest content only of d.txt + $ git commit -a # use latest content of all tracked files + + +File: git.info, Node: Merging, Next: Sharing your changes, Prev: Making changes, Up: Git Quick Reference + +A.5 Merging +=========== + + $ git merge test # merge branch "test" into the current branch + $ git pull git://example.com/project.git master + # fetch and merge in remote branch + $ git pull . test # equivalent to git merge test + + +File: git.info, Node: Sharing your changes, Next: Repository maintenance, Prev: Merging, Up: Git Quick Reference + +A.6 Sharing your changes +======================== + +Importing or exporting patches: + + $ git format-patch origin..HEAD # format a patch for each commit + # in HEAD but not in origin + $ git am mbox # import patches from the mailbox "mbox" + + Fetch a branch in a different Git repository, then merge into the +current branch: + + $ git pull git://example.com/project.git theirbranch + + Store the fetched branch into a local branch before merging into the +current branch: + + $ git pull git://example.com/project.git theirbranch:mybranch + + After creating commits on a local branch, update the remote branch +with your commits: + + $ git push ssh://example.com/project.git mybranch:theirbranch + + When remote and local branch are both named "test": + + $ git push ssh://example.com/project.git test + + Shortcut version for a frequently used remote repository: + + $ git remote add example ssh://example.com/project.git + $ git push example test + + +File: git.info, Node: Repository maintenance, Prev: Sharing your changes, Up: Git Quick Reference + +A.7 Repository maintenance +========================== + +Check for corruption: + + $ git fsck + + Recompress, remove unused cruft: + + $ git gc + + +File: git.info, Node: Notes and todo list for this manual, Prev: Git Quick Reference, Up: Top + +Appendix B Notes and todo list for this manual +********************************************** + +* Menu: + +* Todo list:: + + +File: git.info, Node: Todo list, Up: Notes and todo list for this manual + +B.1 Todo list +============= + +This is a work in progress. + + The basic requirements: + + • It must be readable in order, from beginning to end, by someone + intelligent with a basic grasp of the UNIX command line, but + without any special knowledge of Git. If necessary, any other + prerequisites should be specifically mentioned as they arise. + + • Whenever possible, section headings should clearly describe the + task they explain how to do, in language that requires no more + knowledge than necessary: for example, "importing patches into a + project" rather than "the ‘git am’ command" + + Think about how to create a clear chapter dependency graph that will +allow people to get to important topics without necessarily reading +everything in between. + + Scan ‘Documentation/’ for other stuff left out; in particular: + + • howto’s + + • some of ‘technical/’? + + • hooks + + • list of commands in git(1) (git.html) + + Scan email archives for other stuff left out + + Scan man pages to see if any assume more background than this manual +provides. + + 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? + + Include cross-references to the glossary, where appropriate. + + Add a section on working with other version control systems, +including CVS, Subversion, and just imports of series of release +tarballs. + + Write a chapter on using plumbing and writing scripts. + + Alternates, clone -reference, etc. + + More on recovery from repository corruption. See: +https://lore.kernel.org/git/Pine.LNX.4.64.0702272039540.12485@woody.linux-foundation.org/ +(https://lore.kernel.org/git/Pine.LNX.4.64.0702272039540.12485@woody.linux-foundation.org/) +https://lore.kernel.org/git/Pine.LNX.4.64.0702141033400.3604@woody.linux-foundation.org/ +(https://lore.kernel.org/git/Pine.LNX.4.64.0702141033400.3604@woody.linux-foundation.org/) + + + +Tag Table: +Node: Top212 +Node: idm43164 +Node: Repositories and Branches4465 +Node: How to get a Git repository5070 +Node: How to check out a different version of a project6331 +Node: Understanding History; Commits8890 +Node: Understanding history; commits; parents; and reachability11147 +Node: Understanding history; History diagrams12483 +Node: Understanding history; What is a branch?13224 +Node: Manipulating branches13963 +Node: Examining an old version without creating a new branch15544 +Node: Examining branches from a remote repository17105 +Node: Naming branches; tags; and other references18861 +Node: Updating a repository with git fetch20420 +Node: Fetching branches from other repositories21093 +Node: Exploring Git history22786 +Node: How to use bisect to find a regression23583 +Node: Naming commits26582 +Node: Creating tags28944 +Node: Browsing revisions29512 +Node: Generating diffs31126 +Node: Viewing old file versions31882 +Node: Examples32449 +Node: Counting the number of commits on a branch32902 +Node: Check whether two branches point at the same history33546 +Node: Find first tagged version including a given fix34613 +Node: Showing commits unique to a given branch37277 +Node: Creating a changelog and tarball for a software release39049 +Node: Finding commits referencing a file with given content40885 +Node: Developing with Git41679 +Node: Telling Git your name42152 +Node: Creating a new repository42961 +Node: How to make a commit43476 +Node: Creating good commit messages46371 +Node: Ignoring files47075 +Node: How to merge49098 +Node: Resolving a merge51148 +Node: Getting conflict-resolution help during a merge52517 +Node: Undoing a merge56290 +Node: Fast-forward merges56938 +Node: Fixing mistakes57648 +Node: Fixing a mistake with a new commit58787 +Node: Fixing a mistake by rewriting history59757 +Node: Checking out an old version of a file60906 +Node: Temporarily setting aside work in progress61784 +Node: Ensuring good performance62830 +Node: Ensuring reliability63453 +Node: Checking the repository for corruption63694 +Node: Recovering lost changes64907 +Node: Reflogs65147 +Node: Examining dangling objects67010 +Node: Sharing development with others68647 +Node: Getting updates with git pull69089 +Node: Submitting patches to a project71302 +Node: Importing patches to a project72606 +Node: Public Git repositories73901 +Node: Setting up a public repository76446 +Node: Exporting a Git repository via the Git protocol77232 +Node: Exporting a git repository via HTTP78351 +Node: Pushing changes to a public repository79643 +Node: What to do when a push fails81787 +Node: Setting up a shared repository84199 +Node: Allowing web browsing of a repository85848 +Node: How to get a Git repository with minimal history86654 +Node: Examples <1>87717 +Node: Maintaining topic branches for a Linux subsystem maintainer87952 +Node: Rewriting history and maintaining patch series96755 +Node: Creating the perfect patch series97644 +Node: Keeping a patch series up to date using git rebase99127 +Node: Rewriting a single commit101762 +Node: Reordering or selecting from a patch series102587 +Node: Using interactive rebases103261 +Node: Other tools105631 +Node: Problems with rewriting history105984 +Node: Why bisecting merge commits can be harder than bisecting linear history107811 +Node: Advanced branch management110808 +Node: Fetching individual branches111175 +Node: git fetch and fast-forwards112293 +Node: Forcing git fetch to do non-fast-forward updates113765 +Node: Configuring remote-tracking branches114557 +Node: Git concepts116297 +Node: The Object Database116786 +Node: Commit Object119304 +Node: Tree Object121890 +Node: Blob Object123746 +Node: Trust124995 +Node: Tag Object126433 +Node: How Git stores objects efficiently; pack files127511 +Node: Dangling objects129556 +Node: Recovering from repository corruption133244 +Node: The index137453 +Node: Submodules140334 +Node: Pitfalls with submodules146399 +Node: Low-level Git operations148958 +Node: Object access and manipulation149539 +Node: The Workflow150418 +Node: working directory → index151307 +Node: index → object database153010 +Node: object database → index153601 +Node: index → working directory154258 +Node: Tying it all together155462 +Node: Examining the data158326 +Node: Merging multiple trees159445 +Node: Merging multiple trees; continued161275 +Node: Hacking Git164309 +Node: Object storage format164641 +Node: A birds-eye view of Git’s source code166225 +Node: Git Glossary175147 +Node: Git explained175305 +Ref: [def_alternate_object_database]175403 +Ref: [def_bare_repository]175654 +Ref: [def_blob_object]176236 +Ref: [def_branch]176328 +Ref: [def_cache]176940 +Ref: [def_chain]176995 +Ref: [def_changeset]177248 +Ref: [def_checkout]177449 +Ref: [def_cherry-picking]177877 +Ref: [def_clean]178369 +Ref: [def_commit]178603 +Ref: [def_commit_object]179245 +Ref: [def_commit-ish]179604 +Ref: [def_core_git]180007 +Ref: [def_DAG]180129 +Ref: [def_dangling_object]180454 +Ref: [def_detached_HEAD]180779 +Ref: [def_directory]181857 +Ref: [def_dirty]181904 +Ref: [def_evil_merge]182120 +Ref: [def_fast_forward]182270 +Ref: [def_fetch]182850 +Ref: [def_file_system]183203 +Ref: [def_git_archive]183404 +Ref: [def_gitfile]183496 +Ref: [def_grafts]183627 +Ref: [def_hash]184255 +Ref: [def_head]184344 +Ref: [def_HEAD]184642 +Ref: [def_head_ref]185057 +Ref: [def_hook]185113 +Ref: [def_index]185665 +Ref: [def_index_entry]186003 +Ref: [def_master]186286 +Ref: [def_merge]186617 +Ref: [def_object]187767 +Ref: [def_object_database]187940 +Ref: [def_object_identifier]188168 +Ref: [def_object_name]188245 +Ref: [def_object_type]188464 +Ref: [def_octopus]188724 +Ref: [def_origin]188821 +Ref: [def_overlay]189229 +Ref: [def_pack]189709 +Ref: [def_pack_index]189832 +Ref: [def_pathspec]190013 +Ref: [def_parent]195356 +Ref: [def_pickaxe]195535 +Ref: [def_plumbing]195925 +Ref: [def_porcelain]195989 +Ref: [def_per_worktree_ref]196261 +Ref: [def_pseudoref]196519 +Ref: [def_pull]197410 +Ref: [def_push]197586 +Ref: [def_reachable]198210 +Ref: [def_rebase]198749 +Ref: [def_ref]198931 +Ref: [def_reflog]199697 +Ref: [def_refspec]199977 +Ref: [def_remote]200160 +Ref: [def_remote_tracking_branch]200399 +Ref: [def_repository]200876 +Ref: [def_resolve]201337 +Ref: [def_revision]201454 +Ref: [def_rewind]201523 +Ref: [def_SCM]201680 +Ref: [def_SHA1]201721 +Ref: [def_shallow_clone]201887 +Ref: [def_shallow_repository]202097 +Ref: [def_stash]202846 +Ref: [def_submodule]203029 +Ref: [def_superproject]203241 +Ref: [def_symref]203545 +Ref: [def_tag]203936 +Ref: [def_tag_object]204545 +Ref: [def_topic_branch]204854 +Ref: [def_tree]205198 +Ref: [def_tree_object]205450 +Ref: [def_tree-ish]205703 +Ref: [def_unmerged_index]206327 +Ref: [def_unreachable_object]206451 +Ref: [def_upstream_branch]206655 +Ref: [def_working_tree]206987 +Node: Git Quick Reference207223 +Node: Creating a new repository <1>207713 +Node: Managing branches208146 +Node: Exploring history210068 +Node: Making changes211701 +Node: Merging212411 +Node: Sharing your changes212786 +Node: Repository maintenance213906 +Node: Notes and todo list for this manual214157 +Node: Todo list214376 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: |
