Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-08-16 02:53:37 +0400
committerJunio C Hamano <junkio@cox.net>2005-08-16 02:53:37 +0400
commitda27f4f3f4c23d0276a372726ed050ed13e45168 (patch)
tree8842fbebf0db214d0bc8c68e2918a712b7edede3
parentf4cedd483e5bc4b9553dbc40e084548f7f3bf2ab (diff)
parente31bb3bb939a8feb7af472c55d95f41a90bbc438 (diff)
Merge master changes into rc.
-rw-r--r--Documentation/Makefile1
-rw-r--r--Documentation/git-apply-patch-script.txt4
-rw-r--r--Documentation/git-commit-script.txt17
-rw-r--r--Documentation/git-fetch-script.txt5
-rw-r--r--Documentation/git-log-script.txt45
-rw-r--r--Documentation/git-merge-one-file-script.txt5
-rw-r--r--Documentation/git-pack-objects.txt4
-rw-r--r--Documentation/git-prune-packed.txt42
-rw-r--r--Documentation/git-pull-script.txt5
-rw-r--r--Documentation/git-repack-script.txt40
-rw-r--r--Documentation/git-resolve-script.txt5
-rw-r--r--Documentation/git-shortlog.txt31
-rw-r--r--Documentation/git-show-branches-script.txt69
-rw-r--r--Documentation/git-status-script.txt46
-rw-r--r--Documentation/git-tag-script.txt5
-rw-r--r--Documentation/git-whatchanged.txt61
-rw-r--r--Documentation/git.txt43
-rw-r--r--Documentation/howto/make-dist.txt47
-rw-r--r--Documentation/howto/rebase-and-edit.txt78
-rw-r--r--Documentation/howto/rebase-from-internal-branch.txt163
-rw-r--r--Documentation/howto/using-topic-branches.txt153
-rw-r--r--Makefile1
-rw-r--r--cache.h5
-rw-r--r--fsck-cache.c8
-rwxr-xr-xgit33
-rwxr-xr-xgit-clone-script41
-rwxr-xr-xgit-rebase-script2
-rwxr-xr-xgit-reset-script4
-rwxr-xr-xgit-show-branches-script53
-rwxr-xr-xgit-status-script10
-rwxr-xr-xgit-tag-script2
-rw-r--r--sha1_file.c146
-rw-r--r--templates/hooks--update12
33 files changed, 1054 insertions, 132 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile
index c887ded6af..336578497d 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -53,3 +53,4 @@ clean:
%.xml : %.txt
asciidoc -b docbook -d manpage $<
+
diff --git a/Documentation/git-apply-patch-script.txt b/Documentation/git-apply-patch-script.txt
index a6f860d424..808d3cdc1b 100644
--- a/Documentation/git-apply-patch-script.txt
+++ b/Documentation/git-apply-patch-script.txt
@@ -1,6 +1,6 @@
git-apply-patch-script(1)
=========================
-v0.1, May 2005
+v0.99.4, May 2005
NAME
----
@@ -20,7 +20,7 @@ family of commands report to the current work tree.
Author
------
-Written by Linus Torvalds <torvalds@osdl.org>
+Written by Junio C Hamano <junkio@cox.net>
Documentation
--------------
diff --git a/Documentation/git-commit-script.txt b/Documentation/git-commit-script.txt
index bb559d70a5..cf6b5c3da2 100644
--- a/Documentation/git-commit-script.txt
+++ b/Documentation/git-commit-script.txt
@@ -8,7 +8,7 @@ git-commit-script - Record your changes
SYNOPSIS
--------
-'git commit' [-a] [(-c | -C) <commit> | -F <file> | -m <msg>] <file>...
+'git commit' [-a] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>] <file>...
DESCRIPTION
-----------
@@ -36,13 +36,26 @@ OPTIONS
-m <msg>::
Use the given <msg> as the commit message.
+-s::
+ Add Signed-off-by line at the end of the commit message.
+
+-v::
+ Look for suspicious lines the commit introduces, and
+ abort committing if there is one. The definition of
+ 'suspicious lines' is currently the lines that has
+ trailing whitespaces, and the lines whose indentation
+ has a SP character immediately followed by a TAB
+ character.
+
<file>...::
Update specified paths in the index file.
Author
------
-Written by Linus Torvalds <torvalds@osdl.org>
+Written by Linus Torvalds <torvalds@osdl.org> and
+Junio C Hamano <junkio@cox.net>
+
GIT
---
diff --git a/Documentation/git-fetch-script.txt b/Documentation/git-fetch-script.txt
index 937df05dbc..db3086c732 100644
--- a/Documentation/git-fetch-script.txt
+++ b/Documentation/git-fetch-script.txt
@@ -1,6 +1,6 @@
git-fetch-script(1)
===================
-v0.1, July 2005
+v0.99.4, Aug 2005
NAME
----
@@ -36,7 +36,8 @@ include::pull-fetch-param.txt[]
Author
------
-Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <junkio@cox.net>
+Written by Linus Torvalds <torvalds@osdl.org> and
+Junio C Hamano <junkio@cox.net>
Documentation
--------------
diff --git a/Documentation/git-log-script.txt b/Documentation/git-log-script.txt
new file mode 100644
index 0000000000..ed359bec86
--- /dev/null
+++ b/Documentation/git-log-script.txt
@@ -0,0 +1,45 @@
+git-log-script(1)
+=================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-log-script - Show commit logs
+
+
+SYNOPSIS
+--------
+'git log' <option>...
+
+DESCRIPTION
+-----------
+Shows the commit logs. This command internally invokes
+'git-rev-list', and the command line options are passed to that
+command.
+
+This manual page describes only the most frequently used options.
+
+OPTIONS
+-------
+--pretty=<format>:
+ Controls the way the commit log is formatted.
+
+--max-count=<n>::
+ Limits the number of commits to show.
+
+<since>..<until>::
+ Show only commits between the named two commits.
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+--------------
+Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git-merge-one-file-script.txt b/Documentation/git-merge-one-file-script.txt
index 387601d7e4..1cfe9548e1 100644
--- a/Documentation/git-merge-one-file-script.txt
+++ b/Documentation/git-merge-one-file-script.txt
@@ -1,6 +1,6 @@
git-merge-one-file-script(1)
============================
-v0.1, May 2005
+v0.99.4, Aug 2005
NAME
----
@@ -18,7 +18,8 @@ to resolve a merge after the trivial merge done with "git-read-tree -m".
Author
------
-Written by Linus Torvalds <torvalds@osdl.org>
+Written by Linus Torvalds <torvalds@osdl.org>,
+Junio C Hamano <junkio@cox.net> and Petr Baudis <pasky@suse.cz>.
Documentation
--------------
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 9628183143..7710be0851 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -74,6 +74,10 @@ Documentation
-------------
Documentation by Junio C Hamano
+See-Also
+--------
+git-repack-script(1) git-prune-packed(1)
+
GIT
---
Part of the link:git.html[git] suite
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
new file mode 100644
index 0000000000..893c1df55e
--- /dev/null
+++ b/Documentation/git-prune-packed.txt
@@ -0,0 +1,42 @@
+git-prune-packed(1)
+=====================
+v0.1, August 2005
+
+NAME
+----
+git-prune-packed - Program used to remove the extra object files that are now
+residing in a pack file.
+
+
+SYNOPSIS
+--------
+'git-prune-packed'
+
+DESCRIPTION
+-----------
+This program search the GIT_OBJECT_DIR for all objects that currently exist in
+a pack file as well as the independent object directories.
+
+All such extra objects are removed.
+
+A pack is a collection of objects, individually compressed, with delta
+compression applied, stored in a single file, with an associated index file.
+
+Packs are used to reduce the load on mirror systems, backup engines, disk storage, etc.
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+--------------
+Documentation by Ryan Anderson <ryan@michonline.com>
+
+See-Also
+--------
+git-pack-objects(1) git-repack-script(1)
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git-pull-script.txt b/Documentation/git-pull-script.txt
index ec1e7a2a90..ad9d3ab315 100644
--- a/Documentation/git-pull-script.txt
+++ b/Documentation/git-pull-script.txt
@@ -1,6 +1,6 @@
git-pull-script(1)
==================
-v0.1, May 2005
+v0.99.4, Aug 2005
NAME
----
@@ -25,7 +25,8 @@ include::pull-fetch-param.txt[]
Author
------
-Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <junkio@cox.net>
+Written by Linus Torvalds <torvalds@osdl.org>
+and Junio C Hamano <junkio@cox.net>
Documentation
--------------
diff --git a/Documentation/git-repack-script.txt b/Documentation/git-repack-script.txt
new file mode 100644
index 0000000000..497d0dfe80
--- /dev/null
+++ b/Documentation/git-repack-script.txt
@@ -0,0 +1,40 @@
+git-repack-script(1)
+=====================
+v0.1, August 2005
+
+NAME
+----
+git-repack-script - Script used to pack a repository from a collection of
+objects into pack files.
+
+
+SYNOPSIS
+--------
+'git-repack-script'
+
+DESCRIPTION
+-----------
+This script is used to combine all objects that do not currently reside in a
+"pack", into a pack.
+
+A pack is a collection of objects, individually compressed, with delta
+compression applied, stored in a single file, with an associated index file.
+
+Packs are used to reduce the load on mirror systems, backup engines, disk storage, etc.
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+--------------
+Documentation by Ryan Anderson <ryan@michonline.com>
+
+See-Also
+--------
+git-pack-objects(1) git-prune-packed(1)
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git-resolve-script.txt b/Documentation/git-resolve-script.txt
index 8dd84a381a..99c399a073 100644
--- a/Documentation/git-resolve-script.txt
+++ b/Documentation/git-resolve-script.txt
@@ -1,6 +1,6 @@
git-resolve-script(1)
=====================
-v0.1, May 2005
+v0.99.4, Aug 2005
NAME
----
@@ -18,7 +18,8 @@ This script is used by Linus to merge two trees.
Author
------
-Written by Linus Torvalds <torvalds@osdl.org>
+Written by Linus Torvalds <torvalds@osdl.org> and
+Dan Holmsand <holmsand@gmail.com>.
Documentation
--------------
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
new file mode 100644
index 0000000000..6968ca6060
--- /dev/null
+++ b/Documentation/git-shortlog.txt
@@ -0,0 +1,31 @@
+git-shortlog(1)
+===============
+v0.99.4, Aug 2005
+
+NAME
+----
+git-shortlog - Summarize 'git log' output.
+
+
+SYNOPSIS
+--------
+'git log --pretty=short | git shortlog'
+
+DESCRIPTION
+-----------
+Summarizes 'git log' output in a format suitable for inclusion
+in release announcements.
+
+
+Author
+------
+Written by Jeff Garzik <jgarzik@pobox.com>
+
+Documentation
+--------------
+Documentation by Junio C Hamano.
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git-show-branches-script.txt b/Documentation/git-show-branches-script.txt
new file mode 100644
index 0000000000..95c7013445
--- /dev/null
+++ b/Documentation/git-show-branches-script.txt
@@ -0,0 +1,69 @@
+git-show-branches-script(1)
+===========================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-show-branches-script - Show branches and their commits.
+
+SYNOPSIS
+--------
+'git show-branches <reference>...'
+
+DESCRIPTION
+-----------
+Shows the head commits from the named <reference> (or all refs under
+$GIT_DIR/refs/heads), and displays concise list of commit logs
+to show their relationship semi-visually.
+
+OPTIONS
+-------
+<reference>::
+ Name of the reference under $GIT_DIR/refs/heads/.
+
+
+OUTPUT
+------
+Given N <references>, the first N lines are the one-line
+description from their commit message. The branch head that is
+pointed at by $GIT_DIR/HEAD is prefixed with an asterisk '*'
+character while other heads are prefixed with a '!' character.
+
+Following these N lines, one-line log for each commit is
+displayed, indented N places. If a commit is on the I-th
+branch, the I-th indentation character shows a '+' sign;
+otherwise it shows a space.
+
+The following example shows three branches, "pu", "master" and
+"rc":
+
+ * [pu] Add cheap local clone '-s' flag to git-clone-script
+ ! [master] Documentation updates.
+ ! [rc] Merge master into rc
+ + Add cheap local clone '-s' flag to git-clone-script
+ + Alternate object pool mechanism updates.
+ + Audit rev-parse users.
+ ++ Documentation updates.
+ + Merge master into rc
+ +++ [PATCH] plug memory leak in diff.c::diff_free_filepair()
+
+These three branches all forked from a common commit, "[PATCH]
+plug memory leak...", and "rc" has one commit ahead of it. The
+"master" branch has one different commit that is also shared by
+"pu" branch, and "pu" branch has three more commits on top of
+"master" branch.
+
+
+Author
+------
+Written by Junio C Hamano <junkio@cox.net>
+
+
+Documentation
+--------------
+Documentation by Junio C Hamano.
+
+
+GIT
+---
+Part of the link:git.html[git] suite
diff --git a/Documentation/git-status-script.txt b/Documentation/git-status-script.txt
new file mode 100644
index 0000000000..2fb7f74a0f
--- /dev/null
+++ b/Documentation/git-status-script.txt
@@ -0,0 +1,46 @@
+git-status-script(1)
+====================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-status-script - Show working tree status.
+
+
+SYNOPSIS
+--------
+'git status'
+
+DESCRIPTION
+-----------
+Examines paths in the working tree that has changes unrecorded
+to the index file, and changes between the index file and the
+current HEAD commit. The former paths are what you _could_
+commit by running 'git-update-cache' before running 'git
+commit', and the latter paths are what you _would_ commit by
+running 'git commit'.
+
+If there is no path that is different between the index file and
+the current HEAD commit, the command exits with non-zero
+status.
+
+
+OUTPUT
+------
+The output from this command is designed to be used as a commit
+template comments, and all the output lines are prefixed with '#'.
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org> and
+Junio C Hamano <junkio@cox.net>.
+
+Documentation
+--------------
+Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git-tag-script.txt b/Documentation/git-tag-script.txt
index 2df396ef89..5032acb172 100644
--- a/Documentation/git-tag-script.txt
+++ b/Documentation/git-tag-script.txt
@@ -1,6 +1,6 @@
git-tag-script(1)
=================
-v0.1, May 2005
+v0.99.4, Aug 2005
NAME
----
@@ -27,7 +27,8 @@ A GnuPG signed tag object will be created when "-s" is used.
Author
------
-Written by Linus Torvalds <torvalds@osdl.org>
+Written by Linus Torvalds <torvalds@osdl.org>,
+Junio C Hamano <junkio@cox.net> and Chris Wright <chrisw@osdl.org>.
Documentation
--------------
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
new file mode 100644
index 0000000000..742005353a
--- /dev/null
+++ b/Documentation/git-whatchanged.txt
@@ -0,0 +1,61 @@
+git-whatchanged(1)
+==================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-whatchanged - Show logs with difference each commit introduces.
+
+
+SYNOPSIS
+--------
+'git whatchanged' <option>...
+
+DESCRIPTION
+-----------
+Shows commit logs and diff output each commit introduces. The
+command internally invokes 'git-rev-list' piped to
+'git-diff-tree', and takes command line options for both of
+these commands.
+
+This manual page describes only the most frequently used options.
+
+
+OPTIONS
+-------
+-p::
+ Show textual diffs, instead of the git internal diff
+ output format that is useful only to tell the changed
+ paths and their nature of changes.
+
+--max-count=<n>::
+ Limit output to <n> commits.
+
+<since>..<until>::
+ Limit output to between the two named commits (bottom
+ exclusive, top inclusive).
+
+-r::
+ Show git internal diff output, but for the whole tree,
+ not just the top level.
+
+--pretty=<format>::
+ Controls the output format for the commit logs.
+ <format> can be one of 'raw', 'medium', 'short', 'full',
+ and 'oneline'.
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org> and
+Junio C Hamano <junkio@cox.net>
+
+
+Documentation
+--------------
+Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 1308eb675d..27f362626f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -1,6 +1,6 @@
git(7)
======
-May 2005
+v0.99.4, Aug 2005
NAME
----
@@ -38,7 +38,7 @@ In addition, git itself comes with a spartan set of porcelain
commands. They are usable but are not meant to compete with real
Porcelains.
-There are also some ancilliary programs that can be viewed as useful
+There are also some ancillary programs that can be viewed as useful
aids for using the core commands but which are unlikely to be used by
SCMs layered over git.
@@ -71,6 +71,13 @@ link:git-hash-object.html[git-hash-object]::
link:git-write-tree.html[git-write-tree]::
Creates a tree from the current cache
+link:git-pack-objects.html[git-pack-objects]::
+ Creates a packed archive of objects.
+
+link:git-prune-packed.html[git-prune-packed]::
+ Remove extra objects that are already in pack files.
+
+
Interrogation commands
~~~~~~~~~~~~~~~~~~~~~~
link:git-cat-file.html[git-cat-file]::
@@ -165,8 +172,20 @@ link:git-update-server-info.html[git-update-server-info]::
clients discover references and packs on it.
-Porcelainish Commands
----------------------
+Porcelain-ish Commands
+----------------------
+link:git-whatchanged.html[git-whatchanged]::
+ Shows commit logs and differences they introduce.
+
+link:git-log-script.html[git-log-script]::
+ Shows commit logs.
+
+link:git-shortlog.html[git-shortlog]::
+ Summarizes 'git log' output.
+
+link:git-status-script.html[git-status-script]::
+ Shows the working tree status.
+
link:git-fetch-script.html[git-fetch-script]::
Download from a remote repository via various protocols.
@@ -176,9 +195,15 @@ link:git-pull-script.html[git-pull-script]::
link:git-commit-script.html[git-commit-script]::
Record changes to the repository.
+link:git-show-branches-script.html[git-show-branches-script]::
+ Show branches and their commits.
+
+link:git-repack-script.html[git-repack-script]::
+ Pack unpacked objects in a repository.
+
-Ancilliary Commands
--------------------
+Ancillary Commands
+------------------
Manipulators:
link:git-apply-patch-script.html[git-apply-patch-script]::
@@ -200,7 +225,7 @@ link:git-tag-script.html[git-tag-script]::
An example script to create a tag object signed with GPG
-Interogators:
+Interrogators:
link:git-diff-helper.html[git-diff-helper]::
Generates patch format output for git-diff-*
@@ -240,7 +265,7 @@ Identifier Terminology
Symbolic Identifiers
--------------------
-Any git comand accepting any <object> can also use the following
+Any git command accepting any <object> can also use the following
symbolic notation:
HEAD::
@@ -311,7 +336,7 @@ git so take care if using Cogito etc
'GIT_ALTERNATE_OBJECT_DIRECTORIES'::
Due to the immutable nature of git objects, old objects can be
archived into shared, read-only directories. This variable
- specifies a ":" seperated list of git object directories which
+ specifies a ":" separated list of git object directories which
can be used to search for git objects. New objects will not be
written to these directories.
diff --git a/Documentation/howto/make-dist.txt b/Documentation/howto/make-dist.txt
new file mode 100644
index 0000000000..ae9094157c
--- /dev/null
+++ b/Documentation/howto/make-dist.txt
@@ -0,0 +1,47 @@
+Date: Fri, 12 Aug 2005 22:39:48 -0700 (PDT)
+From: Linus Torvalds <torvalds@osdl.org>
+To: Dave Jones <davej@redhat.com>
+cc: git@vger.kernel.org
+Subject: Re: Fwd: Re: git checkout -f branch doesn't remove extra files
+
+On Sat, 13 Aug 2005, Dave Jones wrote:
+>
+> > Git actually has a _lot_ of nifty tools. I didn't realize that people
+> > didn't know about such basic stuff as "git-tar-tree" and "git-ls-files".
+>
+> Maybe its because things are moving so fast :) Or maybe I just wasn't
+> paying attention on that day. (I even read the git changes via RSS,
+> so I should have no excuse).
+
+Well, git-tar-tree has been there since late April - it's actually one of
+those really early commands. I'm pretty sure the RSS feed came later ;)
+
+I use it all the time in doing releases, it's a lot faster than creating a
+tar tree by reading the filesystem (even if you don't have to check things
+out). A hidden pearl.
+
+This is my crappy "release-script":
+
+ [torvalds@g5 ~]$ cat bin/release-script
+ #!/bin/sh
+ stable="$1"
+ last="$2"
+ new="$3"
+ echo "# git-tag-script v$new"
+ echo "git-tar-tree v$new linux-$new | gzip -9 > ../linux-$new.tar.gz"
+ echo "git-diff-tree -p v$stable v$new | gzip -9 > ../patch-$new.gz"
+ echo "git-rev-list --pretty v$new ^v$last > ../ChangeLog-$new"
+ echo "git-rev-list --pretty=short v$new ^v$last | git-shortlog > ../ShortLog"
+ echo "git-diff-tree -p v$last v$new | git-apply --stat > ../diffstat-$new"
+
+and when I want to do a new kernel release I literally first tag it, and
+then do
+
+ release-script 2.6.12 2.6.13-rc6 2.6.13-rc7
+
+and check that things look sane, and then just cut-and-paste the commands.
+
+Yeah, it's stupid.
+
+ Linus
+
diff --git a/Documentation/howto/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt
new file mode 100644
index 0000000000..8299ca5cdc
--- /dev/null
+++ b/Documentation/howto/rebase-and-edit.txt
@@ -0,0 +1,78 @@
+Date: Sat, 13 Aug 2005 22:16:02 -0700 (PDT)
+From: Linus Torvalds <torvalds@osdl.org>
+To: Steve French <smfrench@austin.rr.com>
+cc: git@vger.kernel.org
+Subject: Re: sending changesets from the middle of a git tree
+
+On Sat, 13 Aug 2005, Linus Torvalds wrote:
+
+> That's correct. Same things apply: you can move a patch over, and create a
+> new one with a modified comment, but basically the _old_ commit will be
+> immutable.
+
+Let me clarify.
+
+You can entirely _drop_ old branches, so commits may be immutable, but
+nothing forces you to keep them. Of course, when you drop a commit, you'll
+always end up dropping all the commits that depended on it, and if you
+actually got somebody else to pull that commit you can't drop it from
+_their_ repository, but undoing things is not impossible.
+
+For example, let's say that you've made a mess of things: you've committed
+three commits "old->a->b->c", and you notice that "a" was broken, but you
+want to save "b" and "c". What you can do is
+
+ # Create a branch "broken" that is the current code
+ # for reference
+ git branch broken
+
+ # Reset the main branch to three parents back: this
+ # effectively undoes the three top commits
+ git reset HEAD^^^
+ git checkout -f
+
+ # Check the result visually to make sure you know what's
+ # going on
+ gitk --all
+
+ # Re-apply the two top ones from "broken"
+ #
+ # First "parent of broken" (aka b):
+ git-diff-tree -p broken^ | git-apply --index
+ git commit --reedit=broken^
+
+ # Then "top of broken" (aka c):
+ git-diff-tree -p broken | git-apply --index
+ git commit --reedit=broken
+
+and you've now re-applied (and possibly edited the comments) the two
+commits b/c, and commit "a" is basically gone (it still exists in the
+"broken" branch, of course).
+
+Finally, check out the end result again:
+
+ # Look at the new commit history
+ gitk --all
+
+to see that everything looks sensible.
+
+And then, you can just remove the broken branch if you decide you really
+don't want it:
+
+ # remove 'broken' branch
+ rm .git/refs/heads/broken
+
+ # Prune old objects if you're really really sure
+ git prune
+
+And yeah, I'm sure there are other ways of doing this. And as usual, the
+above is totally untested, and I just wrote it down in this email, so if
+I've done something wrong, you'll have to figure it out on your own ;)
+
+ Linus
+-
+To unsubscribe from this list: send the line "unsubscribe git" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
+
diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt
new file mode 100644
index 0000000000..8109b7ff26
--- /dev/null
+++ b/Documentation/howto/rebase-from-internal-branch.txt
@@ -0,0 +1,163 @@
+From: Junio C Hamano <junkio@cox.net>
+To: git@vger.kernel.org
+Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
+Subject: Re: sending changesets from the middle of a git tree
+Date: Sun, 14 Aug 2005 18:37:39 -0700
+
+Petr Baudis <pasky@suse.cz> writes:
+
+> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter
+> where Junio C Hamano <junkio@cox.net> told me that...
+>> Linus Torvalds <torvalds@osdl.org> writes:
+>>
+>> > Junio, maybe you want to talk about how you move patches from your "pu"
+>> > branch to the real branches.
+>>
+> Actually, wouldn't this be also precisely for what StGIT is intended to?
+
+Exactly my feeling. I was sort of waiting for Catalin to speak
+up. With its basing philosophical ancestry on quilt, this is
+the kind of task StGIT is designed to do.
+
+I just have done a simpler one, this time using only the core
+GIT tools.
+
+I had a handful commits that were ahead of master in pu, and I
+wanted to add some documentation bypassing my usual habit of
+placing new things in pu first. At the beginning, the commit
+ancestry graph looked like this:
+
+ *"pu" head
+ master --> #1 --> #2 --> #3
+
+So I started from master, made a bunch of edits, and committed:
+
+ $ git checkout master
+ $ cd Documentation; ed git.txt git-apply-patch-script.txt ...
+ $ cd ..; git add Documentation/*.txt
+ $ git commit -s -v
+
+NOTE. The -v flag to commit is a handy way to make sure that
+your additions are not introducing bogusly formatted lines.
+
+After the commit, the ancestry graph would look like this:
+
+ *"pu" head
+ master^ --> #1 --> #2 --> #3
+ \
+ \---> master
+
+The old master is now master^ (the first parent of the master).
+The new master commit holds my documentation updates.
+
+Now I have to deal with "pu" branch.
+
+This is the kind of situation I used to have all the time when
+Linus was the maintainer and I was a contributor, when you look
+at "master" branch being the "maintainer" branch, and "pu"
+branch being the "contributor" branch. Your work started at the
+tip of the "maintainer" branch some time ago, you made a lot of
+progress in the meantime, and now the maintainer branch has some
+other commits you do not have yet. And "git rebase" was written
+with the explicit purpose of helping to maintain branches like
+"pu". You _could_ merge master to pu and keep going, but if you
+eventually want to cherrypick and merge some but not necessarily
+all changes back to the master branch, it often makes later
+operations for _you_ easier if you rebase (i.e. carry forward
+your changes) "pu" rather than merge. So I ran "git rebase":
+
+ $ git checkout pu
+ $ git rebase master pu
+
+What this does is to pick all the commits since the current
+branch (note that I now am on "pu" branch) forked from the
+master branch, and forward port these changes.
+
+ master^ --> #1 --> #2 --> #3
+ \ *"pu" head
+ \---> master --> #1' --> #2' --> #3'
+
+The diff between master^ and #1 is applied to master and
+committed to create #1' commit with the commit information (log,
+author and date) taken from commit #1. On top of that #2' and #3'
+commits are made similarly out of #2 and #3 commits.
+
+Old #3 is not recorded in any of the .git/refs/heads/ file
+anymore, so after doing this you will have dangling commit if
+you ran fsck-cache, which is normal. After testing "pu", you
+can run "git prune" to get rid of those original three commits.
+
+While I am talking about "git rebase", I should talk about how
+to do cherrypicking using only the core GIT tools.
+
+Let's go back to the earlier picture, with different labels.
+
+You, as an individual developer, cloned upstream repository and
+amde a couple of commits on top of it.
+
+ *your "master" head
+ upstream --> #1 --> #2 --> #3
+
+You would want changes #2 and #3 incorporated in the upstream,
+while you feel that #1 may need further improvements. So you
+prepare #2 and #3 for e-mail submission.
+
+ $ git format-patch master^^ master
+
+This creates two files, 0001-XXXX.txt and 0002-XXXX.txt. Send
+them out "To: " your project maintainer and "Cc: " your mailing
+list. You could use contributed script git-send-email-script if
+your host has necessary perl modules for this, but your usual
+MUA would do as long as it does not corrupt whitespaces in the
+patch.
+
+Then you would wait, and you find out that the upstream picked
+up your changes, along with other changes.
+
+ where *your "master" head
+ upstream --> #1 --> #2 --> #3
+ used \
+ to be \--> #A --> #2' --> #3' --> #B --> #C
+ *upstream head
+
+The two commits #2' and #3' in the above picture record the same
+changes your e-mail submission for #2 and #3 contained, but
+probably with the new sign-off line added by the upsteam
+maintainer and definitely with different committer and ancestry
+information, they are different objects from #2 and #3 commits.
+
+You fetch from upstream, but not merge.
+
+ $ git fetch upstream
+
+This leaves the updated upstream head in .git/FETCH_HEAD but
+does not touch your .git/HEAD nor .git/refs/heads/master.
+You run "git rebase" now.
+
+ $ git rebase FETCH_HEAD master
+
+Earlier, I said that rebase applies all the commits from your
+branch on top of the upstream head. Well, I lied. "git rebase"
+is a bit smarter than that and notices that #2 and #3 need not
+be applied, so it only applies #1. The commit ancestry graph
+becomes something like this:
+
+ where *your old "master" head
+ upstream --> #1 --> #2 --> #3
+ used \ your new "master" head*
+ to be \--> #A --> #2' --> #3' --> #B --> #C --> #1'
+ *upstream
+ head
+
+Again, "git prune" would discard the disused commits #1-#3 and
+you continue on starting from the new "master" head, which is
+the #1' commit.
+
+-jc
+
+-
+To unsubscribe from this list: send the line "unsubscribe git" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
+
diff --git a/Documentation/howto/using-topic-branches.txt b/Documentation/howto/using-topic-branches.txt
new file mode 100644
index 0000000000..de28cf7ce7
--- /dev/null
+++ b/Documentation/howto/using-topic-branches.txt
@@ -0,0 +1,153 @@
+Date: Mon, 15 Aug 2005 12:17:41 -0700
+From: tony.luck@intel.com
+Subject: Some tutorial text (was git/cogito workshop/bof at linuxconf au?)
+
+Here's something that I've been putting together on how I'm using
+GIT as a Linux subsystem maintainer.
+
+I suspect that I'm a bit slap-happy with the "git checkout" commands in
+the examples below, and perhaps missing some of the _true-git_ ways of
+doing things.
+
+-Tony
+
+Linux subsystem maintenance using GIT
+-------------------------------------
+
+My requirements here are to be able to create two public trees:
+
+1) 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.
+
+2) 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.)
+
+Note that the period of time that each patch spends in the "test" tree
+is dependent on the complexity of the change. Since GIT does not support
+cherry picking, it is not practical to simply apply all patches to the
+test tree and then pull to the release tree as that would leave trivial
+patches blocked in the test tree waiting for complex changes to accumulate
+enough test time to graduate.
+
+Back in the BitKeeper days I achieved this my creating small forests of
+temporary trees, one tree for each logical grouping of patches, and then
+pulling changes from these trees first to the test tree, and then to the
+release tree. At first I replicated this in GIT, but then I realised
+that I could so this far more efficiently using branches inside a single
+GIT repository.
+
+So here is the step-by-step guide how this all works for me.
+
+First create your work tree by cloning Linus's public tree:
+
+ $ git clone rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work
+
+Change directory into the cloned tree you just created
+
+ $ cd work
+
+Make a GIT branch named "linus", and rename the "origin" branch as linus too:
+
+ $ git checkout -b linus
+ $ mv .git/branches/origin .git/branches/linus
+
+The "linus" branch will be used to track the upstream kernel. To update it,
+you simply run:
+
+ $ git checkout linus && git pull linus
+
+you can do this frequently (as long as you don't have any uncommited work
+in your tree).
+
+If you need to keep track of other public trees, you can add branches for
+them too:
+
+ $ git checkout -b another linus
+ $ echo URL-for-another-public-tree > .git/branches/another
+
+Now create the branches in which you are going to work, these start
+out at the current tip of the linus branch.
+
+ $ git checkout -b test linus
+ $ git checkout -b release linus
+
+These can be easily kept up to date by merging from the "linus" branch:
+
+ $ git checkout test && git resolve test linus "Auto-update from upstream"
+ $ git checkout release && git resolve release linus "Auto-update from upstream"
+
+Set up so that you can push upstream to your public tree:
+
+ $ echo master.kernel.org:/ftp/pub/scm/linux/kernel/git/aegl/linux-2.6.git > .git/branches/origin
+
+and then push each of the test and release branches using:
+
+ $ git push origin test
+and
+ $ git push origin 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 the current tip of the
+linus branch:
+
+ $ git checkout -b speed-up-spinlocks linus
+
+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 pull it into the
+"test" branch in preparation to make it public:
+
+ $ git checkout test && git resolve test speed-up-spinlocks "Pull speed-up-spinlock changes"
+
+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.
+
+Some time 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 checkout release && git resolve release speed-up-spinlocks "Pull speed-up-spinlock changes"
+
+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-whatchanged branchname ^linus | git-shortlog
+
+To see whether it has already been merged into the test or release branches
+use:
+
+ $ git-rev-list branchname ^test
+or
+ $ git-rev-list branchname ^release
+
+[If this branch has not yet been merged you will see a set of SHA1 values
+for the commits, 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 "linus" branch)
+the branch for this change is no longer needed. You detect this when the
+output from:
+
+ $ git-rev-list branchname ^linus
+
+is empty. At this point the branch can be deleted:
+
+ $ rm .git/refs/heads/branchname
+
+To create diffstat and shortlog summaries of changes to include in a "please
+pull" request to Linus you can use:
+
+ $ git-whatchanged -p release ^linus | diffstat -p1
+and
+ $ git-whatchanged release ^linus | git-shortlog
+
diff --git a/Makefile b/Makefile
index ff3d7e3fad..1623247273 100644
--- a/Makefile
+++ b/Makefile
@@ -71,6 +71,7 @@ SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \
SCRIPTS += git-count-objects-script
# SCRIPTS += git-send-email-script
SCRIPTS += git-revert-script
+SCRIPTS += git-show-branches-script
PROG= git-update-cache git-diff-files git-init-db git-write-tree \
git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/cache.h b/cache.h
index efd2a2c595..dbde95a0b6 100644
--- a/cache.h
+++ b/cache.h
@@ -278,9 +278,10 @@ struct checkout {
extern int checkout_entry(struct cache_entry *ce, struct checkout *state);
extern struct alternate_object_database {
- char *base;
+ struct alternate_object_database *next;
char *name;
-} *alt_odb;
+ char base[0]; /* more */
+} *alt_odb_list;
extern void prepare_alt_odb(void);
extern struct packed_git {
diff --git a/fsck-cache.c b/fsck-cache.c
index e40c64332f..8091780193 100644
--- a/fsck-cache.c
+++ b/fsck-cache.c
@@ -456,13 +456,13 @@ int main(int argc, char **argv)
fsck_head_link();
fsck_object_dir(get_object_directory());
if (check_full) {
- int j;
+ struct alternate_object_database *alt;
struct packed_git *p;
prepare_alt_odb();
- for (j = 0; alt_odb[j].base; j++) {
+ for (alt = alt_odb_list; alt; alt = alt->next) {
char namebuf[PATH_MAX];
- int namelen = alt_odb[j].name - alt_odb[j].base;
- memcpy(namebuf, alt_odb[j].base, namelen);
+ int namelen = alt->name - alt->base;
+ memcpy(namebuf, alt->base, namelen);
namebuf[namelen - 1] = 0;
fsck_object_dir(namebuf);
}
diff --git a/git b/git
index 9f511956ae..0d8b382aa9 100755
--- a/git
+++ b/git
@@ -1,19 +1,22 @@
#!/bin/sh
-cmd="$1"
-shift
-if which git-$cmd-script >& /dev/null
-then
- exec git-$cmd-script "$@"
-fi
-if which git-$cmd >& /dev/null
-then
- exec git-$cmd "$@"
-fi
+cmd=
+path=$(dirname $0)
+case "$#" in
+0) ;;
+*) cmd="$1"
+ shift
+ test -x $path/git-$cmd-script && exec $path/git-$cmd-script "$@"
+ test -x $path/git-$cmd && exec $path/git-$cmd "$@" ;;
+esac
-alternatives=($(echo $PATH | tr ':' '\n' | while read i; do ls $i/git-*-script 2> /dev/null; done))
+echo "Usage: git COMMAND [OPTIONS] [TARGET]"
+if [ -n "$cmd" ]; then
+ echo " git command '$cmd' not found: commands are:"
+else
+ echo " git commands are:"
+fi
-echo Git command "'$cmd'" not found. Try one of
-for i in "${alternatives[@]}"; do
- echo $i | sed 's:^.*/git-: :' | sed 's:-script$::'
-done | sort | uniq
+alternatives=$(cd $path &&
+ ls git-*-script | sed -e 's/git-//' -e 's/-script//')
+echo $alternatives | fmt | sed 's/^/ /'
diff --git a/git-clone-script b/git-clone-script
index 60dc2a9d88..909ccc5301 100755
--- a/git-clone-script
+++ b/git-clone-script
@@ -6,7 +6,7 @@
# Clone a repository into a different directory that does not yet exist.
usage() {
- echo >&2 "* git clone [-l] [-q] [-u <upload-pack>] <repo> <dir>"
+ echo >&2 "* git clone [-l [-s]] [-q] [-u <upload-pack>] <repo> <dir>"
exit 1
}
@@ -16,11 +16,14 @@ get_repo_base() {
quiet=
use_local=no
+local_shared=no
upload_pack=
while
case "$#,$1" in
0,*) break ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
+ *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
+ local_shared=yes ;;
*,-q|*,--quiet) quiet=-q ;;
1,-u|1,--upload-pack) usage ;;
*,-u|*,--upload-pack)
@@ -57,22 +60,30 @@ yes,yes)
exit 1
}
- # See if we can hardlink and drop "l" if not.
- sample_file=$(cd "$repo" && \
- find objects -type f -print | sed -e 1q)
+ case "$local_shared" in
+ no)
+ # See if we can hardlink and drop "l" if not.
+ sample_file=$(cd "$repo" && \
+ find objects -type f -print | sed -e 1q)
- # objects directory should not be empty since we are cloning!
- test -f "$repo/$sample_file" || exit
+ # objects directory should not be empty since we are cloning!
+ test -f "$repo/$sample_file" || exit
- l=
- if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null
- then
- l=l
- fi &&
- rm -f "$D/.git/objects/sample" &&
- cd "$repo" &&
- find objects -type f -print |
- cpio -puamd$l "$D/.git/" || exit 1
+ l=
+ if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null
+ then
+ l=l
+ fi &&
+ rm -f "$D/.git/objects/sample" &&
+ cd "$repo" &&
+ find objects -type f -print |
+ cpio -puamd$l "$D/.git/" || exit 1
+ ;;
+ yes)
+ mkdir -p "$D/.git/objects/info"
+ echo "$repo/objects" >"$D/.git/objects/info/alternates"
+ ;;
+ esac
# Make a duplicate of refs and HEAD pointer
HEAD=
diff --git a/git-rebase-script b/git-rebase-script
index 7779813d11..026225ab2c 100755
--- a/git-rebase-script
+++ b/git-rebase-script
@@ -28,7 +28,7 @@ case "$#" in
esac
git-read-tree -m -u $ours $upstream &&
-echo "$upstream" >"$GIT_DIR/HEAD" || exit
+git-rev-parse --verify "$upstream^0" >"$GIT_DIR/HEAD" || exit
tmp=.rebase-tmp$$
fail=$tmp-fail
diff --git a/git-reset-script b/git-reset-script
index 49994df7a2..7da8d86823 100755
--- a/git-reset-script
+++ b/git-reset-script
@@ -1,7 +1,7 @@
#!/bin/sh
. git-sh-setup-script || die "Not a git archive"
-rev=$(git-rev-parse --revs-only --verify --default HEAD "$@") || exit
-rev=$(git-rev-parse --revs-only --verify $rev^0) || exit
+rev=$(git-rev-parse --verify --default HEAD "$@") || exit
+rev=$(git-rev-parse --verify $rev^0) || exit
git-read-tree --reset "$rev" && {
if orig=$(git-rev-parse --verify HEAD 2>/dev/null)
then
diff --git a/git-show-branches-script b/git-show-branches-script
new file mode 100755
index 0000000000..263025c476
--- /dev/null
+++ b/git-show-branches-script
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Show refs and their recent commits.
+#
+
+. git-sh-setup-script || die "Not a git repository"
+
+headref=`readlink $GIT_DIR/HEAD`
+case "$#" in
+0)
+ set x `cd $GIT_DIR/refs &&
+ find heads -type f -print |
+ sed -e 's|heads/||' |
+ sort`
+ shift ;;
+esac
+
+hh= in=
+for ref
+do
+ case "/$headref" in
+ */"$ref") H='*' ;;
+ *) H='!' ;;
+ esac
+ h=`git-rev-parse --verify "$ref^0"` || exit
+ l=`git-log-script --max-count=1 --pretty=oneline "$h" |
+ sed -e 's/^[^ ]* //'`
+ hh="$hh $h"
+ echo "$in$H [$ref] $l"
+ in="$in "
+done
+set x $hh
+shift
+
+git-rev-list --pretty=oneline "$@" |
+while read v l
+do
+ in=''
+ for h
+ do
+ b=`git-merge-base $h $v`
+ case "$b" in
+ $v) in="$in+" ;;
+ *) in="$in " ;;
+ esac
+ done
+
+ echo "$in $l"
+ case "$in" in
+ *' '*) ;;
+ *) break ;;
+ esac
+done
diff --git a/git-status-script b/git-status-script
index e9a0383441..947cc21975 100755
--- a/git-status-script
+++ b/git-status-script
@@ -1,4 +1,6 @@
#!/bin/sh
+. git-sh-setup-script || die "Not a git archive"
+
report () {
header="#
# $1:
@@ -26,7 +28,7 @@ report () {
[ "$header" ]
}
-git-update-cache --refresh >& /dev/null
+git-update-cache --refresh >/dev/null 2>&1
git-diff-cache -M --cached HEAD | sed 's/^://' | report "Updated but not checked in" "will commit"
committable="$?"
git-diff-files | sed 's/^://' | report "Changed but not updated" "use git-update-cache to mark for commit"
@@ -35,4 +37,10 @@ then
echo "nothing to commit"
exit 1
fi
+branch=`readlink "$GIT_DIR/HEAD"`
+case "$branch" in
+refs/heads/master) ;;
+*) echo "#
+# On branch $branch" ;;
+esac
exit 0
diff --git a/git-tag-script b/git-tag-script
index d3074a8b3d..39c3c53987 100755
--- a/git-tag-script
+++ b/git-tag-script
@@ -47,7 +47,7 @@ if [ -e "$GIT_DIR/refs/tags/$name" -a -z "$force" ]; then
fi
shift
-object=$(git-rev-parse --verify --revs-only --default HEAD "$@") || exit 1
+object=$(git-rev-parse --verify --default HEAD "$@") || exit 1
type=$(git-cat-file -t $object) || exit 1
tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1
diff --git a/sha1_file.c b/sha1_file.c
index 8d189d4919..2d109f928b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -222,84 +222,100 @@ char *sha1_pack_index_name(const unsigned char *sha1)
return base;
}
-struct alternate_object_database *alt_odb;
+struct alternate_object_database *alt_odb_list;
+static struct alternate_object_database **alt_odb_tail;
/*
* Prepare alternate object database registry.
- * alt_odb points at an array of struct alternate_object_database.
- * This array is terminated with an element that has both its base
- * and name set to NULL. alt_odb[n] comes from n'th non-empty
- * element from colon separated ALTERNATE_DB_ENVIRONMENT environment
- * variable, and its base points at a statically allocated buffer
- * that contains "/the/directory/corresponding/to/.git/objects/...",
- * while its name points just after the slash at the end of
- * ".git/objects/" in the example above, and has enough space to hold
- * 40-byte hex SHA1, an extra slash for the first level indirection,
- * and the terminating NUL.
- * This function allocates the alt_odb array and all the strings
- * pointed by base fields of the array elements with one xmalloc();
- * the string pool immediately follows the array.
+ *
+ * The variable alt_odb_list points at the list of struct
+ * alternate_object_database. The elements on this list come from
+ * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT
+ * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates,
+ * whose contents is exactly in the same format as that environment
+ * variable. Its base points at a statically allocated buffer that
+ * contains "/the/directory/corresponding/to/.git/objects/...", while
+ * its name points just after the slash at the end of ".git/objects/"
+ * in the example above, and has enough space to hold 40-byte hex
+ * SHA1, an extra slash for the first level indirection, and the
+ * terminating NUL.
*/
-void prepare_alt_odb(void)
+static void link_alt_odb_entries(const char *alt, const char *ep)
{
- int pass, totlen, i;
const char *cp, *last;
- char *op = NULL;
- const char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
+ struct alternate_object_database *ent;
+
+ last = alt;
+ do {
+ for (cp = last; cp < ep && *cp != ':'; cp++)
+ ;
+ if (last != cp) {
+ /* 43 = 40-byte + 2 '/' + terminating NUL */
+ int pfxlen = cp - last;
+ int entlen = pfxlen + 43;
+
+ ent = xmalloc(sizeof(*ent) + entlen);
+ *alt_odb_tail = ent;
+ alt_odb_tail = &(ent->next);
+ ent->next = NULL;
+
+ memcpy(ent->base, last, pfxlen);
+ ent->name = ent->base + pfxlen + 1;
+ ent->base[pfxlen] = ent->base[pfxlen + 3] = '/';
+ ent->base[entlen-1] = 0;
+ }
+ while (cp < ep && *cp == ':')
+ cp++;
+ last = cp;
+ } while (cp < ep);
+}
- if (alt_odb)
+void prepare_alt_odb(void)
+{
+ char path[PATH_MAX];
+ char *map, *ep;
+ int fd;
+ struct stat st;
+ char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
+
+ sprintf(path, "%s/info/alternates", get_object_directory());
+ if (alt_odb_tail)
+ return;
+ alt_odb_tail = &alt_odb_list;
+ link_alt_odb_entries(alt, alt + strlen(alt));
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return;
+ if (fstat(fd, &st) || (st.st_size == 0)) {
+ close(fd);
return;
- /* The first pass counts how large an area to allocate to
- * hold the entire alt_odb structure, including array of
- * structs and path buffers for them. The second pass fills
- * the structure and prepares the path buffers for use by
- * fill_sha1_path().
- */
- for (totlen = pass = 0; pass < 2; pass++) {
- last = alt;
- i = 0;
- do {
- cp = strchr(last, ':') ? : last + strlen(last);
- if (last != cp) {
- /* 43 = 40-byte + 2 '/' + terminating NUL */
- int pfxlen = cp - last;
- int entlen = pfxlen + 43;
- if (pass == 0)
- totlen += entlen;
- else {
- alt_odb[i].base = op;
- alt_odb[i].name = op + pfxlen + 1;
- memcpy(op, last, pfxlen);
- op[pfxlen] = op[pfxlen + 3] = '/';
- op[entlen-1] = 0;
- op += entlen;
- }
- i++;
- }
- while (*cp && *cp == ':')
- cp++;
- last = cp;
- } while (*cp);
- if (pass)
- break;
- alt_odb = xmalloc(sizeof(*alt_odb) * (i + 1) + totlen);
- alt_odb[i].base = alt_odb[i].name = NULL;
- op = (char*)(&alt_odb[i+1]);
}
+ map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ if (map == MAP_FAILED)
+ return;
+
+ /* Remove the trailing newline */
+ for (ep = map + st.st_size - 1; map < ep && ep[-1] == '\n'; ep--)
+ ;
+ link_alt_odb_entries(map, ep);
+ munmap(map, st.st_size);
}
static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
{
- int i;
char *name = sha1_file_name(sha1);
+ struct alternate_object_database *alt;
if (!stat(name, st))
return name;
prepare_alt_odb();
- for (i = 0; (name = alt_odb[i].name) != NULL; i++) {
+ for (alt = alt_odb_list; alt; alt = alt->next) {
+ name = alt->name;
fill_sha1_path(name, sha1);
- if (!stat(alt_odb[i].base, st))
- return alt_odb[i].base;
+ if (!stat(alt->base, st))
+ return alt->base;
}
return NULL;
}
@@ -522,18 +538,18 @@ static void prepare_packed_git_one(char *objdir)
void prepare_packed_git(void)
{
- int i;
static int run_once = 0;
+ struct alternate_object_database *alt;
- if (run_once++)
+ if (run_once)
return;
-
prepare_packed_git_one(get_object_directory());
prepare_alt_odb();
- for (i = 0; alt_odb[i].base != NULL; i++) {
- alt_odb[i].name[0] = 0;
- prepare_packed_git_one(alt_odb[i].base);
+ for (alt = alt_odb_list; alt; alt = alt->next) {
+ alt->name[0] = 0;
+ prepare_packed_git_one(alt->base);
}
+ run_once = 1;
}
int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
diff --git a/templates/hooks--update b/templates/hooks--update
index 540ade0d52..0726975367 100644
--- a/templates/hooks--update
+++ b/templates/hooks--update
@@ -1,6 +1,7 @@
#!/bin/sh
#
# An example hook script to mail out commit update information.
+# Called by git-receive-pack with arguments: refname sha1-old sha1-new
#
# To enable this hook:
# (1) change the recipient e-mail address
@@ -12,10 +13,15 @@ recipient="commit-list@mydomain.xz"
if expr "$2" : '0*$' >/dev/null
then
echo "Created a new ref, with the following commits:"
- git-rev-list --pretty "$2"
+ git-rev-list --pretty "$3"
else
- echo "New commits:"
- git-rev-list --pretty "$3" "^$2"
+ $base=$(git-merge-base "$2" "$3")
+ if [ $base == "$2" ]; then
+ echo "New commits:"
+ else
+ echo "Rebased ref, commits from common ancestor:"
+fi
+git-rev-list --pretty "$3" "^$base"
fi |
mail -s "Changes to ref $1" "$recipient"
exit 0