Merge with http://members.cox.net/junkio/git-jc.git
authorPetr Baudis <pasky@ucw.cz>
Wed, 11 May 2005 00:00:49 +0000 (02:00 +0200)
committerPetr Baudis <xpasky@machine.sinus.cz>
Wed, 11 May 2005 00:00:49 +0000 (02:00 +0200)
63 files changed:
Documentation/Makefile [new file with mode: 0644]
Documentation/core-git.txt [deleted file]
Documentation/diff-format.txt [new file with mode: 0644]
Documentation/git-apply-patch-script.txt [new file with mode: 0644]
Documentation/git-cat-file.txt [new file with mode: 0644]
Documentation/git-check-files.txt [new file with mode: 0644]
Documentation/git-checkout-cache.txt [new file with mode: 0644]
Documentation/git-commit-tree.txt [new file with mode: 0644]
Documentation/git-convert-cache.txt [new file with mode: 0644]
Documentation/git-diff-cache.txt [new file with mode: 0644]
Documentation/git-diff-files.txt [new file with mode: 0644]
Documentation/git-diff-tree-helper.txt [new file with mode: 0644]
Documentation/git-diff-tree.txt [new file with mode: 0644]
Documentation/git-export.txt [new file with mode: 0644]
Documentation/git-fsck-cache.txt [new file with mode: 0644]
Documentation/git-http-pull.txt [new file with mode: 0644]
Documentation/git-init-db.txt [new file with mode: 0644]
Documentation/git-local-pull.txt [new file with mode: 0644]
Documentation/git-ls-files.txt [new file with mode: 0644]
Documentation/git-ls-tree.txt [new file with mode: 0644]
Documentation/git-merge-base.txt [new file with mode: 0644]
Documentation/git-merge-cache.txt [new file with mode: 0644]
Documentation/git-merge-one-file-script.txt [new file with mode: 0644]
Documentation/git-mktag.txt [new file with mode: 0644]
Documentation/git-prune-script.txt [new file with mode: 0644]
Documentation/git-pull-script.txt [new file with mode: 0644]
Documentation/git-read-tree.txt [new file with mode: 0644]
Documentation/git-resolve-script.txt [new file with mode: 0644]
Documentation/git-rev-list.txt [new file with mode: 0644]
Documentation/git-rev-tree.txt [new file with mode: 0644]
Documentation/git-rpull.txt [new file with mode: 0644]
Documentation/git-rpush.txt [new file with mode: 0644]
Documentation/git-tag-script.txt [new file with mode: 0644]
Documentation/git-tar-tree.txt [new file with mode: 0644]
Documentation/git-unpack-file.txt [new file with mode: 0644]
Documentation/git-update-cache.txt [new file with mode: 0644]
Documentation/git-write-blob.txt [new file with mode: 0644]
Documentation/git-write-tree.txt [new file with mode: 0644]
Documentation/git.txt [new file with mode: 0644]
Makefile
README
cache.h
checkout-cache.c
commit-tree.c
diff-cache.c
diff-tree-helper.c
diff.c
fsck-cache.c
git-apply-patch-script
git-merge-one-file-script
git-prune-script
git-pull-script
git-resolve-script
git-tag-script
gitenv.c [new file with mode: 0644]
init-db.c
local-pull.c
read-cache.c
rsh.c
sha1_file.c
tree.c
update-cache.c
write-tree.c

diff --git a/Documentation/Makefile b/Documentation/Makefile
new file mode 100644 (file)
index 0000000..b23991d
--- /dev/null
@@ -0,0 +1,24 @@
+DOC_SRC=$(wildcard git*.txt)
+DOC_HTML=$(patsubst %.txt,%.html,$(DOC_SRC))
+DOC_MAN=$(patsubst %.txt,%.1,$(DOC_SRC))
+
+all: $(DOC_HTML) $(DOC_MAN)
+
+html: $(DOC_HTML)
+
+man: $(DOC_MAN)
+
+git-%: %.c $(LIB_FILE)
+       $(CC) $(CFLAGS) -o $@ $(filter %.c,$^) $(LIBS)
+
+clean:
+       rm -f *.xml *.html *.1
+
+%.html : %.txt
+       asciidoc -b css-embedded -d manpage $<
+
+%.1 : %.xml
+       xmlto man $<
+
+%.xml : %.txt
+       asciidoc -b docbook -d manpage $<
diff --git a/Documentation/core-git.txt b/Documentation/core-git.txt
deleted file mode 100644 (file)
index 8bd8931..0000000
+++ /dev/null
@@ -1,1307 +0,0 @@
-This file contains reference information for the core git commands.
-
-The README contains much useful definition and clarification
-info - read that first.  And of the commands, I suggest reading
-'git-update-cache' and 'git-read-tree' first - I wish I had!
-
-David Greaves <david@dgreaves.com>
-24/4/05
-
-Updated by Junio C Hamano <junkio@cox.net> on 2005-05-05 to
-reflect recent changes.
-
-Identifier terminology used:
-
-<object>
-       Indicates any object sha1 identifier
-
-<blob>
-       Indicates a blob object sha1 identifier
-
-<tree>
-       Indicates a tree object sha1 identifier
-
-<commit>
-       Indicates a commit object sha1 identifier
-
-<tree-ish>
-       Indicates a tree, commit or tag object sha1 identifier.
-       A command that takes a <tree-ish> argument ultimately
-       wants to operate on a <tree> object but automatically
-       dereferences <commit> and <tag> that points at a
-       <tree>.
-
-<type>
-       Indicates that an object type is required.
-       Currently one of: blob/tree/commit/tag
-
-<file>
-       Indicates a filename - always relative to the root of
-       the tree structure GIT_INDEX_FILE describes.
-
-
-################################################################
-git-apply-patch-script
-
-This is a sample script to be used as GIT_EXTERNAL_DIFF to apply
-differences git-diff-* family of commands reports to the current
-work tree.
-
-
-################################################################
-git-cat-file
-       git-cat-file (-t | <type>) <object>
-
-Provides contents or type of objects in the repository. The type
-is required if -t is not being used to find the object type.
-
-<object>
-       The sha1 identifier of the object.
-
--t
-       Instead of the content, show the object type identified
-       by <object>.
-
-<type>
-       Typically this matches the real type of <object> but
-       asking for type that can trivially dereferenced from the
-       given <object> is also permitted.  An example is to ask
-       "tree" with <object> for a commit object that contains
-       it, or to ask "blob" with <object> for a tag object that
-       points at it.
-
-Output
-
-If -t is specified, one of the <type>.
-
-Otherwise the raw (though uncompressed) contents of the <object> will
-be returned.
-
-
-################################################################
-git-check-files
-       git-check-files <file>...
-
-Check that a list of files are up-to-date between the filesystem and
-the cache. Used to verify a patch target before doing a patch.
-
-Files that do not exist on the filesystem are considered up-to-date
-(whether or not they are in the cache).
-
-Emits an error message on failure.
-preparing to update existing file <file> not in cache
-         <file> exists but is not in the cache
-
-preparing to update file <file> not uptodate in cache
-         <file> on disk is not up-to-date with the cache
-
-Exits with a status code indicating success if all files are
-up-to-date.
-
-see also: git-update-cache
-
-
-################################################################
-git-checkout-cache
-       git-checkout-cache [-q] [-a] [-f] [-n] [--prefix=<string>]
-                          [--] <file>...
-
-Will copy all files listed from the cache to the working directory
-(not overwriting existing files).
-
--q
-       be quiet if files exist or are not in the cache
-
--f
-       forces overwrite of existing files
-
--a
-       checks out all files in the cache (will then continue to
-       process listed files).
-
--n
-       Don't checkout new files, only refresh files already checked
-       out.
-
---prefix=<string>
-       When creating files, prepend <string> (usually a directory
-       including a trailing /)
-
---
-       Do not interpret any more arguments as options.
-
-Note that the order of the flags matters:
-
-       git-checkout-cache -a -f file.c
-
-will first check out all files listed in the cache (but not overwrite
-any old ones), and then force-checkout file.c a second time (ie that
-one _will_ overwrite any old contents with the same filename).
-
-Also, just doing "git-checkout-cache" does nothing. You probably meant
-"git-checkout-cache -a". And if you want to force it, you want
-"git-checkout-cache -f -a".
-
-Intuitiveness is not the goal here. Repeatability is. The reason for
-the "no arguments means no work" thing is that from scripts you are
-supposed to be able to do things like
-
-       find . -name '*.h' -print0 | xargs -0 git-checkout-cache -f --
-
-which will force all existing *.h files to be replaced with their
-cached copies. If an empty command line implied "all", then this would
-force-refresh everything in the cache, which was not the point.
-
-To update and refresh only the files already checked out:
-
-   git-checkout-cache -n -f -a && git-update-cache --ignore-missing --refresh
-
-Oh, and the "--" is just a good idea when you know the rest will be
-filenames. Just so that you wouldn't have a filename of "-a" causing
-problems (not possible in the above example, but get used to it in
-scripting!).
-
-The prefix ability basically makes it trivial to use git-checkout-cache as
-a "git-export as tree" function. Just read the desired tree into the
-index, and do a
-  
-        git-checkout-cache --prefix=git-export-dir/ -a
-  
-and git-checkout-cache will "git-export" the cache into the specified
-directory.
-  
-NOTE! The final "/" is important. The git-exported name is literally just
-prefixed with the specified string, so you can also do something like
-  
-        git-checkout-cache --prefix=.merged- Makefile
-  
-to check out the currently cached copy of "Makefile" into the file
-".merged-Makefile".
-
-
-################################################################
-git-commit-tree
-       git-commit-tree <tree> [-p <parent commit>]*   < changelog
-
-Creates a new commit object based on the provided tree object and
-emits the new commit object id on stdout. If no parent is given then
-it is considered to be an initial tree.
-
-A commit object usually has 1 parent (a commit after a change) or up
-to 16 parents.  More than one parent represents a merge of branches
-that led to them.
-
-While a tree represents a particular directory state of a working
-directory, a commit represents that state in "time", and explains how
-to get there.
-
-Normally a commit would identify 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 ".git/HEAD", so that we can
-always see what the last committed state was.
-
-Options
-
-<tree>
-       An existing tree object
-
--p <parent commit>
-       Each -p indicates a the id of a parent commit object.
-       
-
-Commit Information
-
-A commit encapsulates:
-       all parent object ids
-       author name, email and date
-       committer name and email and the commit time.
-
-If not provided, git-commit-tree uses your name, hostname and domain to
-provide author and committer info. This can be overridden using the
-following environment variables.
-       AUTHOR_NAME
-       AUTHOR_EMAIL
-       AUTHOR_DATE
-       COMMIT_AUTHOR_NAME
-       COMMIT_AUTHOR_EMAIL
-(nb <,> and '\n's are stripped)
-
-A commit comment is read from stdin (max 999 chars). If a changelog
-entry is not provided via '<' redirection, git-commit-tree will just wait
-for one to be entered and terminated with ^D
-
-see also: git-write-tree
-
-
-################################################################
-git-convert-cache
-
-Converts old-style GIT repository to the latest.
-
-
-################################################################
-git-diff-cache
-       git-diff-cache [-p] [-r] [-z] [--cached] <tree-ish>
-
-Compares the content and mode of the blobs found via a tree object
-with the content of the current cache and, optionally ignoring the
-stat state of the file on disk.
-
-<tree-ish>
-       The id of a tree object to diff against.
-
--p
-       Generate patch (see section on generating patches)
-
--r
-       This flag does not mean anything.  It is there only to match
-       git-diff-tree.  Unlike git-diff-tree, git-diff-cache always looks
-       at all the subdirectories.
-
--z
-       \0 line termination on output
-
---cached
-       do not consider the on-disk file at all
-
-Output format:
-
-See "Output format from git-diff-cache, git-diff-tree and git-diff-files"
-section.
-
-Operating Modes
-
-You can choose whether you want to trust the index file entirely
-(using the "--cached" flag) or ask the diff logic to show any files
-that don't match the stat state as being "tentatively changed".  Both
-of these operations are very useful indeed.
-
-Cached Mode
-
-If --cached is specified, it allows you to ask:
-
-       show me the differences between HEAD and the current index
-       contents (the ones I'd write with a "git-write-tree")
-
-For example, let's say that you have worked on your index file, and are
-ready to commit. You want to see eactly _what_ you are going to commit is
-without having to write a new tree object and compare it that way, and to
-do that, you just do
-
-       git-diff-cache --cached $(cat .git/HEAD)
-
-Example: let's say I had renamed "commit.c" to "git-commit.c", and I had
-done an "git-update-cache" to make that effective in the index file.
-"git-diff-files" wouldn't show anything at all, since the index file
-matches my working directory. But doing a git-diff-cache does:
-
-  torvalds@ppc970:~/git> git-diff-cache --cached $(cat .git/HEAD)
-  -100644 blob    4161aecc6700a2eb579e842af0b7f22b98443f74        commit.c
-  +100644 blob    4161aecc6700a2eb579e842af0b7f22b98443f74        git-commit.c
-
-You can trivially see that the above is a rename.
-
-In fact, "git-diff-cache --cached" _should_ always be entirely equivalent to
-actually doing a "git-write-tree" and comparing that. Except this one is much
-nicer for the case where you just want to check where you are.
-
-So doing a "git-diff-cache --cached" is basically very useful when you are 
-asking yourself "what have I already marked for being committed, and 
-what's the difference to a previous tree".
-
-Non-cached Mode
-
-The "non-cached" mode takes a different approach, and is potentially the
-even more useful of the two in that what it does can't be emulated with a
-"git-write-tree + git-diff-tree". Thus that's the default mode.  The
-non-cached version asks the question
-
-   "show me the differences between HEAD and the currently checked out 
-    tree - index contents _and_ files that aren't up-to-date"
-
-which is obviously a very useful question too, since that tells you what
-you _could_ commit. Again, the output matches the "git-diff-tree -r"
-output to a tee, but with a twist.
-
-The twist is that if some file doesn't match the cache, we don't have a
-backing store thing for it, and we use the magic "all-zero" sha1 to show
-that. So let's say that you have edited "kernel/sched.c", but have not
-actually done an git-update-cache on it yet - there is no "object" associated
-with the new state, and you get:
-
-  torvalds@ppc970:~/v2.6/linux> git-diff-cache $(cat .git/HEAD )
-  *100644->100664 blob    7476bb......->000000......      kernel/sched.c
-
-ie it shows that the tree has changed, and that "kernel/sched.c" has is
-not up-to-date and may contain new stuff. The all-zero sha1 means that to
-get the real diff, you need to look at the object in the working directory
-directly rather than do an object-to-object diff.
-
-NOTE! As with other commands of this type, "git-diff-cache" does not
-actually look at the contents of the file at all. So maybe
-"kernel/sched.c" hasn't actually changed, and it's just that you touched
-it. In either case, it's a note that you need to upate-cache it to make
-the cache be in sync.
-
-NOTE 2! You can have a mixture of files show up as "has been updated" and
-"is still dirty in the working directory" together. You can always tell
-which file is in which state, since the "has been updated" ones show a
-valid sha1, and the "not in sync with the index" ones will always have the
-special all-zero sha1.
-
-
-################################################################
-git-diff-tree
-       git-diff-tree [-p] [-r] [-z] [--stdin] [-m] [-s] [-v] <tree-ish> <tree-ish> [<pattern>]*
-
-Compares the content and mode of the blobs found via two tree objects.
-
-Note that git-diff-tree can use the tree encapsulated in a commit object.
-
-<tree-ish>
-       The id of a tree object.
-
-<pattern>
-       If provided, the results are limited to a subset of files
-       matching one of these prefix strings.
-       ie file matches /^<pattern1>|<pattern2>|.../
-       Note that pattern does not provide any wildcard or regexp
-       features.
-
--p
-       generate patch (see section on generating patches).  For
-       git-diff-tree, this flag implies -r as well.
-
--r
-       recurse
-
--z
-       \0 line termination on output
-
---stdin
-       When --stdin is specified, the command does not take
-       <tree-ish> arguments from the command line.  Instead, it
-       reads either one <commit> or a pair of <tree-ish>
-       separated with a single space from its standard input.
-
-        When a single commit is given on one line of such input,
-        it compares the commit with its parents.  The following
-        flags further affects its behaviour.  This does not
-        apply to the case where two <tree-ish> separated with a
-        single space are given.
-
--m
-       By default, "git-diff-tree --stdin" does not show
-       differences for merge commits.  With this flag, it shows
-       differences to that commit from all of its parents.
-
--s
-       By default, "git-diff-tree --stdin" shows differences,
-       either in machine-readable form (without -p) or in patch
-       form (with -p).  This output can be supressed.  It is
-       only useful with -v flag.
-
--v
-       This flag causes "git-diff-tree --stdin" to also show
-       the commit message before the differences.
-
-
-Limiting Output
-
-If you're only interested in differences in a subset of files, for
-example some architecture-specific files, you might do:
-
-       git-diff-tree -r <tree-ish> <tree-ish> arch/ia64 include/asm-ia64
-
-and it will only show you what changed in those two directories.
-
-Or if you are searching for what changed in just kernel/sched.c, just do
-
-       git-diff-tree -r <tree-ish> <tree-ish> kernel/sched.c
-
-and it will ignore all differences to other files.
-
-The pattern is always the prefix, and is matched exactly.  There are no
-wildcards.  Even stricter, it has to match complete path comonent.
-I.e. "foo" does not pick up "foobar.h".  "foo" does match "foo/bar.h"
-so it can be used to name subdirectories.
-
-Output format:
-
-See "Output format from git-diff-cache, git-diff-tree and git-diff-files"
-section.
-
-An example of normal usage is:
-
-  torvalds@ppc970:~/git> git-diff-tree 5319e4......
-  *100664->100664 blob    ac348b.......->a01513.......      git-fsck-cache.c
-
-which tells you that the last commit changed just one file (it's from
-this one:
-
-  commit 3c6f7ca19ad4043e9e72fa94106f352897e651a8
-  tree 5319e4d609cdd282069cc4dce33c1db559539b03
-  parent b4e628ea30d5ab3606119d2ea5caeab141d38df7
-  author Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
-  committer Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
-
-  Make "git-fsck-cache" print out all the root commits it finds.
-
-  Once I do the reference tracking, I'll also make it print out all the
-  HEAD commits it finds, which is even more interesting.
-
-in case you care).
-
-
-################################################################
-git-diff-tree-helper
-       git-diff-tree-helper [-z] [-R]
-
-Reads output from git-diff-cache, git-diff-tree and git-diff-files and
-generates patch format output.
-
--z
-       \0 line termination on input
-
--R
-       Output diff in reverse.  This is useful for displaying output from
-       git-diff-cache which always compares tree with cache or working
-       file.  E.g.
-
-       git-diff-cache <tree> | git-diff-tree-helper -R file.c
-
-       would show a diff to bring the working file back to what is in the
-       <tree>.
-
-See also the section on generating patches.
-
-
-################################################################
-git-fsck-cache
-       git-fsck-cache [--tags] [--root] [[--unreachable] [--cache] <object>*]
-
-Verifies the connectivity and validity of the objects in the database.
-
-<object>
-       An object to treat as the head of an unreachability trace.
-
---unreachable
-       Print out objects that exist but that aren't readable from any
-       of the specified head nodes.
-
---root
-       Report root nodes.
-
---tags
-       Report tags.
-
---cache
-       Consider any object recorded in the cache also as a head node for
-       an unreachability trace.
-
-It tests SHA1 and general object sanity, and it does full tracking of
-the resulting reachability and everything else. It prints out any
-corruption it finds (missing or bad objects), and if you use the
-"--unreachable" flag it will also print out objects that exist but
-that aren't readable from any of the specified head nodes.
-
-So for example
-
-       git-fsck-cache --unreachable $(cat .git/HEAD)
-
-or, for Cogito users:
-
-       git-fsck-cache --unreachable $(cat .git/refs/heads/*)
-
-will do quite a _lot_ of verification on the tree. There are a few
-extra validity tests to be added (make sure that tree objects are
-sorted properly etc), but on the whole if "git-fsck-cache" is happy, you
-do have a valid tree.
-
-Any corrupt objects you will have to find in backups or other archives
-(ie you can just remove them and do an "rsync" with some other site in
-the hopes that somebody else has the object you have corrupted).
-
-Of course, "valid tree" doesn't mean that it wasn't generated by some
-evil person, and the end result might be crap. Git is a revision
-tracking system, not a quality assurance system ;)
-
-Extracted Diagnostics
-
-expect dangling commits - potential heads - due to lack of head information
-       You haven't specified any nodes as heads so it won't be
-       possible to differentiate between un-parented commits and
-       root nodes.
-
-missing sha1 directory '<dir>'
-       The directory holding the sha1 objects is missing.
-
-unreachable <type> <object>
-       The <type> object <object>, isn't actually referred to directly
-       or indirectly in any of the trees or commits seen. This can
-       mean that there's another root na SHA1_ode that you're not specifying
-       or that the tree is corrupt. If you haven't missed a root node
-       then you might as well delete unreachable nodes since they
-       can't be used.
-
-missing <type> <object>
-       The <type> object <object>, is referred to but isn't present in
-       the database.
-
-dangling <type> <object>
-       The <type> object <object>, is present in the database but never
-       _directly_ used. A dangling commit could be a root node.
-
-warning: git-fsck-cache: tree <tree> has full pathnames in it
-       And it shouldn't...
-
-sha1 mismatch <object>
-       The database has an object who's sha1 doesn't match the
-       database value.
-       This indicates a ??serious?? data integrity problem.
-       (note: this error occured during early git development when
-       the database format changed.)
-
-Environment Variables
-
-SHA1_FILE_DIRECTORY
-       used to specify the object database root (usually .git/objects)
-
-GIT_INDEX_FILE
-       used to specify the cache
-
-
-################################################################
-git-export
-       git-export top [base]
-
-Exports each commit and diff against each of its parents, between
-top and base.  If base is not specified it exports everything.
-
-
-################################################################
-git-init-db
-       git-init-db
-
-This simply creates an empty git object database - basically a .git
-directory and .git/object/??/ directories.
-
-If the object storage directory is specified via the SHA1_FILE_DIRECTORY
-environment variable then the sha1 directories are created underneath -
-otherwise the default .git/objects directory is used.
-
-git-init-db won't hurt an existing repository.
-
-
-################################################################
-git-http-pull
-
-       git-http-pull [-c] [-t] [-a] [-v] commit-id url
-
-Downloads a remote GIT repository via HTTP protocol.
-
--c
-       Get the commit objects.
--t
-       Get trees associated with the commit objects.
--a
-       Get all the objects.
--v
-       Report what is downloaded.
-
-
-################################################################
-git-local-pull
-
-       git-local-pull [-c] [-t] [-a] [-l] [-s] [-n] [-v] commit-id path
-
-Downloads another GIT repository on a local system.
-
--c
-       Get the commit objects.
--t
-       Get trees associated with the commit objects.
--a
-       Get all the objects.
--v
-       Report what is downloaded.
-
-################################################################
-git-ls-tree
-       git-ls-tree [-r] [-z] <tree-ish>
-
-Converts the tree object to a human readable (and script processable)
-form.
-
-<tree-ish>
-       Id of a tree.
-
--r
-       recurse into sub-trees
-
--z
-       \0 line termination on output
-
-Output Format
-<mode>\t       <type>\t        <object>\t      <file>
-
-
-################################################################
-git-merge-base
-       git-merge-base <commit> <commit>
-
-git-merge-base finds as good a common ancestor as possible. Given a
-selection of equally good common ancestors it should not be relied on
-to decide in any particular way.
-
-The git-merge-base algorithm is still in flux - use the source...
-
-
-################################################################
-git-merge-cache
-       git-merge-cache <merge-program> (-a | -- | <file>*) 
-
-This looks up the <file>(s) in the cache and, if there are any merge
-entries, passes the SHA1 hash for those files as arguments 1, 2, 3 (empty
-argument if no file), and <file> as argument 4.  File modes for the three
-files are passed as arguments 5, 6 and 7.
-
---
-       Interpret all future arguments as filenames.
-
--a
-       Run merge against all files in the cache that need merging.
-
-If git-merge-cache is called with multiple <file>s (or -a) then it
-processes them in turn only stopping if merge returns a non-zero exit
-code.
-
-Typically this is run with the a script calling the merge command from
-the RCS package.
-
-A sample script called git-merge-one-file-script is included in the
-ditribution.
-
-ALERT ALERT ALERT! The git "merge object order" is different from the
-RCS "merge" program merge object order. In the above ordering, the
-original is first. But the argument order to the 3-way merge program
-"merge" is to have the original in the middle. Don't ask me why.
-
-Examples:
-
-  torvalds@ppc970:~/merge-test> git-merge-cache cat MM
-  This is MM from the original tree.                   # original
-  This is modified MM in the branch A.                 # merge1
-  This is modified MM in the branch B.                 # merge2
-  This is modified MM in the branch B.                 # current contents
-
-or 
-
-  torvalds@ppc970:~/merge-test> git-merge-cache cat AA MM
-  cat: : No such file or directory
-  This is added AA in the branch A.
-  This is added AA in the branch B.
-  This is added AA in the branch B.
-  fatal: merge program failed
-
-where the latter example shows how "git-merge-cache" will stop trying to
-merge once anything has returned an error (ie "cat" returned an error
-for the AA file, because it didn't exist in the original, and thus
-"git-merge-cache" didn't even try to merge the MM thing).
-
-################################################################
-git-merge-one-file-script
-
-This is the standard helper program to use with git-merge-cache
-to resolve a merge after the trivial merge done with git-read-tree -m.
-
-################################################################
-git-mktag
-
-Reads a tag contents from its standard input and creates a tag object.
-The input must be a well formed tag object.
-
-
-################################################################
-git-prune-script
-
-This runs git-fsck-cache --unreachable program using the heads specified
-on the command line (or .git/refs/heads/* and .git/refs/tags/* if none is
-specified), and prunes all unreachable objects from the object database.
-
-
-################################################################
-git-pull-script
-
-This script is used by Linus to pull from a remote repository and perform
-a merge.
-
-
-################################################################
-git-read-tree
-       git-read-tree (<tree-ish> | -m <tree-ish1> [<tree-ish2> <tree-ish3>])"
-
-Reads the tree information given by <tree> into the directory cache,
-but does not actually _update_ any of the files it "caches". (see:
-git-checkout-cache)
-
-Optionally, it can merge a tree into the cache or perform a 3-way
-merge.
-
-Trivial merges are done by git-read-tree itself.  Only conflicting paths
-will be in unmerged state when git-read-tree returns.
-
--m
-       Perform a merge, not just a read
-
-<tree-ish#>
-       The id of the tree object(s) to be read/merged.
-
-
-Merging
-If -m is specified, git-read-tree performs 2 kinds of merge, a single tree
-merge if only 1 tree is given or a 3-way merge if 3 trees are
-provided.
-
-Single Tree Merge
-If only 1 tree is specified, git-read-tree operates as if the user did not
-specify "-m", except that if the original cache has an entry for a
-given pathname; and the contents of the path matches with the tree
-being read, the stat info from the cache is used. (In other words, the
-cache's stat()s take precedence over the merged tree's)
-
-That means that if you do a "git-read-tree -m <newtree>" followed by a
-"git-checkout-cache -f -a", the git-checkout-cache only checks out the stuff
-that really changed.
-
-This is used to avoid unnecessary false hits when git-diff-files is
-run after git-read-tree.
-
-3-Way Merge
-Each "index" entry has two bits worth of "stage" state. stage 0 is the
-normal one, and is the only one you'd see in any kind of normal use.
-
-However, when you do "git-read-tree" with three trees, the "stage"
-starts out at 1.
-
-This means that you can do
-
-       git-read-tree -m <tree1> <tree2> <tree3>
-
-and you will end up with an index with all of the <tree1> entries in
-"stage1", all of the <tree2> entries in "stage2" and all of the
-<tree3> entries in "stage3".
-
-Furthermore, "git-read-tree" has special-case logic that says: if you see
-a file that matches in all respects in the following states, it
-"collapses" back to "stage0":
-
-   - stage 2 and 3 are the same; take one or the other (it makes no
-     difference - the same work has been done on stage 2 and 3)
-
-   - stage 1 and stage 2 are the same and stage 3 is different; take
-     stage 3 (some work has been done on stage 3)
-
-   - stage 1 and stage 3 are the same and stage 2 is different take
-     stage 2 (some work has been done on stage 2)
-
-The git-write-tree command refuses to write a nonsensical tree, and it
-will complain about unmerged entries if it sees a single entry that is not
-stage 0.
-
-Ok, this all sounds like a collection of totally nonsensical rules,
-but it's actually exactly what you want in order to do a fast
-merge. The different stages represent the "result tree" (stage 0, aka
-"merged"), the original tree (stage 1, aka "orig"), and the two trees
-you are trying to merge (stage 2 and 3 respectively).
-
-In fact, the way "git-read-tree" works, it's entirely agnostic about how
-you assign the stages, and you could really assign them any which way,
-and the above is just a suggested way to do it (except since
-"git-write-tree" refuses to write anything but stage0 entries, it makes
-sense to always consider stage 0 to be the "full merge" state).
-
-So what happens? Try it out. Select the original tree, and two trees
-to merge, and look how it works:
-
- - if a file exists in identical format in all three trees, it will 
-   automatically collapse to "merged" state by the new git-read-tree.
-
- - a file that has _any_ difference what-so-ever in the three trees
-   will stay as separate entries in the index. It's up to "script
-   policy" to determine how to remove the non-0 stages, and insert a
-   merged version.  But since the index is always sorted, they're easy
-   to find: they'll be clustered together.
-
- - the index file saves and restores with all this information, so you
-   can merge things incrementally, but as long as it has entries in
-   stages 1/2/3 (ie "unmerged entries") you can't write the result.
-
-So now the merge algorithm ends up being really simple:
-
- - you walk the index in order, and ignore all entries of stage 0,
-   since they've already been done.
-
- - if you find a "stage1", but no matching "stage2" or "stage3", you
-   know it's been removed from both trees (it only existed in the
-   original tree), and you remove that entry.  - if you find a
-   matching "stage2" and "stage3" tree, you remove one of them, and
-   turn the other into a "stage0" entry. Remove any matching "stage1"
-   entry if it exists too.  .. all the normal trivial rules ..
-
-Incidentally - it also means that you don't even have to have a separate
-subdirectory for this. All the information literally is in the index file,
-which is a temporary thing anyway. There is no need to worry about what is
-in the working directory, since it is never shown and never used.
-
-see also:
-git-write-tree
-git-ls-files
-
-
-################################################################
-git-resolve-script
-
-This script is used by Linus to merge two trees.
-
-
-################################################################
-git-rev-list <commit>
-
-Lists commit objects in reverse chronological order starting at the
-given commit, taking ancestry relationship into account.  This is
-useful to produce human-readable log output.
-
-
-################################################################
-git-rev-tree
-       git-rev-tree [--edges] [--cache <cache-file>] [^]<commit> [[^]<commit>]
-
-Provides the revision tree for one or more commits.
-
---edges
-       Show edges (ie places where the marking changes between parent
-       and child)
-
---cache <cache-file>
-       Use the specified file as a cache from a previous git-rev-list run
-       to speed things up.  Note that this "cache" is totally different
-       concept from the directory index.  Also this option is not
-       implemented yet.
-
-[^]<commit>
-       The commit id to trace (a leading caret means to ignore this
-       commit-id and below)
-
-Output:
-<date> <commit>:<flags> [<parent-commit>:<flags> ]*
-
-<date>
-       Date in 'seconds since epoch'
-
-<commit>
-       id of commit object
-
-<parent-commit>
-       id of each parent commit object (>1 indicates a merge)
-
-<flags>
-
-       The flags are read as a bitmask representing each commit
-       provided on the commandline. eg: given the command:
-
-                $ git-rev-tree <com1> <com2> <com3>
-
-       The output:
-
-           <date> <commit>:5
-
-        means that <commit> is reachable from <com1>(1) and <com3>(4)
-       
-A revtree can get quite large. git-rev-tree will eventually allow you to
-cache previous state so that you don't have to follow the whole thing
-down.
-
-So the change difference between two commits is literally
-
-       git-rev-tree [commit-id1]  > commit1-revtree
-       git-rev-tree [commit-id2]  > commit2-revtree
-       join -t : commit1-revtree commit2-revtree > common-revisions
-
-(this is also how to find the most common parent - you'd look at just
-the head revisions - the ones that aren't referred to by other
-revisions - in "common-revision", and figure out the best one. I
-think.)
-
-
-################################################################
-git-rpull
-
-       git-rpull [-c] [-t] [-a] [-v] commit-id url
-
-Pulls from a remote repository over ssh connection, invoking git-rpush on
-the other end.
-
--c
-       Get the commit objects.
--t
-       Get trees associated with the commit objects.
--a
-       Get all the objects.
--v
-       Report what is downloaded.
-
-
-################################################################
-git-rpush
-
-Helper "server-side" program used by git-rpull.
-
-
-################################################################
-git-diff-files
-       git-diff-files [-p] [-q] [-r] [-z] [<pattern>...]
-
-Compares the files in the working tree and the cache.  When paths
-are specified, compares only those named paths.  Otherwise all
-entries in the cache are compared.  The output format is the
-same as git-diff-cache and git-diff-tree.
-
--p
-       generate patch (see section on generating patches).
-
--q
-       Remain silent even on nonexisting files
-
--r
-       This flag does not mean anything.  It is there only to match
-       git-diff-tree.  Unlike git-diff-tree, git-diff-files always looks
-       at all the subdirectories.
-
-
-Output format:
-
-See "Output format from git-diff-cache, git-diff-tree and git-diff-files"
-section.
-
-
-################################################################
-git-tag-script
-
-This is an example script that uses git-mktag to create a tag object
-signed with GPG.
-
-
-################################################################
-git-tar-tree
-
-       git-tar-tree <tree-ish> [ <base> ]
-
-Creates a tar archive containing the tree structure for the named tree.
-When <base> is specified it is added as a leading path as the files in the
-generated tar archive.
-
-
-################################################################
-git-ls-files
-       git-ls-files [-z] [-t]
-               (--[cached|deleted|others|ignored|stage|unmerged])*
-               (-[c|d|o|i|s|u])*
-               [-x <pattern>|--exclude=<pattern>]
-               [-X <file>|--exclude-from=<file>]
-
-This merges the file listing in the directory cache index with the
-actual working directory list, and shows different combinations of the
-two.
-
-One or more of the options below may be used to determine the files
-shown:
-
--c|--cached
-       Show cached files in the output (default)
-
--d|--deleted
-       Show deleted files in the output
-
--o|--others
-       Show other files in the output
-
--i|--ignored
-       Show ignored files in the output
-       Note the this also reverses any exclude list present.
-
--s|--stage
-       Show stage files in the output
-
--u|--unmerged
-       Show unmerged files in the output (forces --stage)
-
--z
-       \0 line termination on output
-
--x|--exclude=<pattern>
-       Skips files matching pattern.
-       Note that pattern is a shell wildcard pattern.
-
--X|--exclude-from=<file>
-       exclude patterns are read from <file>; 1 per line.
-       Allows the use of the famous dontdiff file as follows to find
-       out about uncommitted files just as dontdiff is used with
-       the diff command:
-            git-ls-files --others --exclude-from=dontdiff
-
--t
-       Identify the file status with the following tags (followed by
-       a space) at the start of each line:
-       H       cached
-       M       unmerged
-       R       removed/deleted
-       ?       other
-
-Output
-show files just outputs the filename unless --stage is specified in
-which case it outputs:
-
-[<tag> ]<mode> <object> <stage> <file>
-
-git-ls-files --unmerged" and "git-ls-files --stage " can be used to examine
-detailed information on unmerged paths.
-
-For an unmerged path, instead of recording a single mode/SHA1 pair,
-the dircache records up to three such pairs; one from tree O in stage
-1, A in stage 2, and B in stage 3.  This information can be used by
-the user (or Cogito) to see what should eventually be recorded at the
-path. (see read-cache for more information on state)
-
-see also:
-read-cache
-
-
-################################################################
-git-unpack-file
-       git-unpack-file <blob>
-
-Creates a file holding the contents of the blob specified by sha1. It
-returns the name of the temporary file in the following format:
-       .merge_file_XXXXX
-
-<blob>
-       Must be a blob id
-
-################################################################
-git-update-cache
-       git-update-cache
-            [--add] [--remove] [--refresh]
-            [--ignore-missing]
-            [--force-remove <file>]
-            [--cacheinfo <mode> <object> <file>]*
-            [--] [<file>]*
-
-Modifies the index or directory cache. Each file mentioned is updated
-into the cache and any 'unmerged' or 'needs updating' state is
-cleared.
-
-The way git-update-cache handles files it is told about can be modified
-using the various options:
-
---add
-       If a specified file isn't in the cache already then it's
-       added.
-       Default behaviour is to ignore new files.
-
---remove
-       If a specified file is in the cache but is missing then it's
-       removed.
-       Default behaviour is to ignore removed file.
-
---refresh
-       Looks at the current cache and checks to see if merges or
-       updates are needed by checking stat() information.
-
---ignore-missing
-       Ignores missing files during a --refresh
-
---cacheinfo <mode> <object> <path>
-       Directly insert the specified info into the cache.
-       
---force-remove
-       Remove the file from the index even when the working directory
-       still has such a file.
-
---
-       Do not interpret any more arguments as options.
-
-<file>
-       Files to act on.
-       Note that files begining with '.' are discarded. This includes
-       "./file" and "dir/./file". If you don't want this, then use     
-       cleaner names.
-       The same applies to directories ending '/' and paths with '//'
-
-Using --refresh
---refresh does not calculate a new sha1 file or bring the cache
-up-to-date for mode/content changes. But what it _does_ do is to
-"re-match" the stat information of a file with the cache, so that you
-can refresh the cache for a file that hasn't been changed but where
-the stat entry is out of date.
-
-For example, you'd want to do this after doing a "git-read-tree", to link
-up the stat cache details with the proper files.
-
-Using --cacheinfo
---cacheinfo is used to register a file that is not in the current
-working directory.  This is useful for minimum-checkout merging.
-
-To pretend you have a file with mode and sha1 at path, say:
-
- $ git-update-cache --cacheinfo mode sha1 path
-
-To update and refresh only the files already checked out:
-
-   git-checkout-cache -n -f -a && git-update-cache --ignore-missing --refresh
-
-
-################################################################
-git-write-blob
-
-       git-write-blob <any-file-on-the-filesystem>
-
-Writes the contents of the named file (which can be outside of the work
-tree) as a blob into the object database, and reports its object ID to its
-standard output.  This is used by git-merge-one-file-script to update the
-cache without modifying files in the work tree.
-
-
-################################################################
-git-write-tree
-       git-write-tree
-
-Creates a tree object using the current cache.
-
-The cache must be merged.
-
-Conceptually, git-write-tree sync()s the current directory cache contents
-into a set of tree files.
-In order to have that match what is actually in your directory right
-now, you need to have done a "git-update-cache" phase before you did the
-"git-write-tree".
-
-
-################################################################
-
-Output format from git-diff-cache, git-diff-tree and git-diff-files.
-
-These commands all compare two sets of things; what are
-compared are different:
-
-    git-diff-cache <tree-ish>
-
-        compares the <tree-ish> and the files on the filesystem.
-
-    git-diff-cache --cached <tree-ish>
-
-        compares the <tree-ish> and the cache.
-
-    git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]
-
-        compares the trees named by the two arguments.
-
-    git-diff-files [<pattern>...]
-
-        compares the cache and the files on the filesystem.
-
-The following desription uses "old" and "new" to mean those
-compared entities.
-
-For files in old but not in new (i.e. removed):
--<mode> \t <type> \t <object> \t <path>
-
-For files not in old but in new (i.e. added):
-+<mode> \t <type> \t <object> \t <path>
-
-For files that differ:
-*<old-mode>-><new-mode> \t <type> \t <old-sha1>-><new-sha1> \t <path>
-
-<new-sha1> is shown as all 0's if new is a file on the
-filesystem and it is out of sync with the cache.  Example:
-
-  *100644->100644 blob    5be4a4.......->000000.......      file.c
-
-################################################################
-
-Generating patches
-
-When git-diff-cache, git-diff-tree, or git-diff-files are run with a -p
-option, they do not produce the output described in "Output format from
-git-diff-cache, git-diff-tree and git-diff-files" section.  It instead
-produces a patch file.
-
-The patch generation can be customized at two levels.  This
-customization also applies to git-diff-tree-helper.
-
-1. When the environment variable GIT_EXTERNAL_DIFF is not set,
-   these commands internally invoke diff like this:
-
-   diff -L a/<path> -L a/<path> -pu <old> <new>
-
-   For added files, /dev/null is used for <old>.  For removed
-   files, /dev/null is used for <new>
-
-   The diff formatting options can be customized via the
-   environment variable GIT_DIFF_OPTS.  For example, if you
-   prefer context diff:
-
-   GIT_DIFF_OPTS=-c git-diff-cache -p $(cat .git/HEAD)
-
-
-2. When the environment variable GIT_EXTERNAL_DIFF is set, the
-   program named by it is called, instead of the diff invocation
-   described above.
-
-   For a path that is added, removed, or modified,
-   GIT_EXTERNAL_DIFF is called with 7 parameters:
-
-     path old-file old-hex old-mode new-file new-hex new-mode
-
-   where
-     <old|new>-file are files GIT_EXTERNAL_DIFF can use to read the
-                    contents of <old|ne>,
-     <old|new>-hex are the 40-hexdigit SHA1 hashes,
-     <old|new>-mode are the octal representation of the file modes.
-
-   The file parameters can point at the user's working file (e.g. new-file
-   in git-diff-files), /dev/null (e.g. old-file when a new file is added),
-   or a temporary file (e.g. old-file in the cache).  GIT_EXTERNAL_DIFF
-   should not worry about unlinking the temporary file --- it is removed
-   when GIT_EXTERNAL_DIFF exits.
-
-   For a path that is unmerged, GIT_EXTERNAL_DIFF is called with
-   1 parameter, path.
-
-################################################################
-
-Terminology: - see README for description
-Each line contains terms used interchangeably
-
-object database, .git directory
-directory cache, index
-id, sha1, sha1-id, sha1 hash
-type, tag
-blob, blob object
-tree, tree object
-commit, commit object
-parent
-root object
-changeset
-
-
-git Environment Variables
-AUTHOR_NAME
-AUTHOR_EMAIL
-AUTHOR_DATE
-COMMIT_AUTHOR_NAME
-COMMIT_AUTHOR_EMAIL
-GIT_DIFF_OPTS
-GIT_EXTERNAL_DIFF
-GIT_INDEX_FILE
-SHA1_FILE_DIRECTORY
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
new file mode 100644 (file)
index 0000000..1a99e85
--- /dev/null
@@ -0,0 +1,89 @@
+The output format from "git-diff-cache", "git-diff-tree" and
+"git-diff-files" is very similar.
+
+These commands all compare two sets of things; what are
+compared are different:
+
+git-diff-cache <tree-ish>::
+        compares the <tree-ish> and the files on the filesystem.
+
+git-diff-cache --cached <tree-ish>::
+        compares the <tree-ish> and the cache.
+
+git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]::
+        compares the trees named by the two arguments.
+
+git-diff-files [<pattern>...]::
+        compares the cache and the files on the filesystem.
+
+The following desription uses "old" and "new" to mean those
+compared entities.
+
+For files in old but not in new (i.e. removed):
+
+    -<mode> \t <type> \t <object> \t <path>
+
+For files not in old but in new (i.e. added):
+
+    +<mode> \t <type> \t <object> \t <path>
+
+For files that differ:
+
+    *<old-mode>-><new-mode> \t <type> \t <old-sha1>-><new-sha1> \t <path>
+
+<new-sha1> is shown as all 0's if new is a file on the
+filesystem and it is out of sync with the cache.  Example:
+
+  *100644->100644 blob    5be4a4.......->000000.......      file.c
+
+
+Generating patches with -p
+--------------------------
+
+When "git-diff-cache", "git-diff-tree", or "git-diff-files" are run
+with a '-p' option, they do not produce the output described above
+instead they produce a patch file.
+
+The patch generation can be customized at two levels.  This
+customization also applies to "git-diff-tree-helper".
+
+1. When the environment variable 'GIT_EXTERNAL_DIFF' is not set,
+   these commands internally invoke "diff" like this:
+
+      diff -L a/<path> -L a/<path> -pu <old> <new>
++
+For added files, `/dev/null` is used for <old>.  For removed
+files, `/dev/null` is used for <new>
++
+The "diff" formatting options can be customized via the
+environment variable 'GIT_DIFF_OPTS'.  For example, if you
+prefer context diff:
+
+      GIT_DIFF_OPTS=-c git-diff-cache -p $(cat .git/HEAD)
+
+
+2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
+   program named by it is called, instead of the diff invocation
+   described above.
++
+For a path that is added, removed, or modified,
+'GIT_EXTERNAL_DIFF' is called with 7 parameters:
+
+     path old-file old-hex old-mode new-file new-hex new-mode
++
+where:
+
+     <old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
+                     contents of <old|ne>,
+     <old|new>-hex:: are the 40-hexdigit SHA1 hashes,
+     <old|new>-mode:: are the octal representation of the file modes.
+
++ 
+The file parameters can point at the user's working file
+(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
+when a new file is added), or a temporary file (e.g. `old-file` in the
+cache).  'GIT_EXTERNAL_DIFF' should not worry about unlinking the
+temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
+
+For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
+parameter, <path>.
diff --git a/Documentation/git-apply-patch-script.txt b/Documentation/git-apply-patch-script.txt
new file mode 100644 (file)
index 0000000..a6f860d
--- /dev/null
@@ -0,0 +1,32 @@
+git-apply-patch-script(1)
+=========================
+v0.1, May 2005
+
+NAME
+----
+git-apply-patch-script - Sample script to apply the diffs from git-diff-*
+
+
+SYNOPSIS
+--------
+'git-apply-patch-script'
+
+DESCRIPTION
+-----------
+This is a sample script to be used via the 'GIT_EXTERNAL_DIFF'
+environment variable to apply the differences that the "git-diff-*"
+family of commands report to the current work tree.
+
+
+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-cat-file.txt b/Documentation/git-cat-file.txt
new file mode 100644 (file)
index 0000000..48fb377
--- /dev/null
@@ -0,0 +1,55 @@
+git-cat-file(1)
+===============
+v0.1, May 2005
+
+NAME
+----
+git-cat-file - Provide content or type information for repository objects
+
+
+SYNOPSIS
+--------
+'git-cat-file' (-t | <type>) <object>
+
+DESCRIPTION
+-----------
+Provides content or type of objects in the repository. The type
+is required if '-t' is not being used to find the object type.
+
+OPTIONS
+-------
+<object>::
+       The sha1 identifier of the object.
+
+-t::
+       Instead of the content, show the object type identified by
+       <object>.
+
+<type>::
+       Typically this matches the real type of <object> but asking
+       for a type that can trivially dereferenced from the given
+       <object> is also permitted.  An example is to ask for a
+       "tree" with <object> being a commit object that contains it,
+       or to ask for a "blob" with <object> being a tag object that
+       points at it.
+
+OUTPUT
+------
+If '-t' is specified, one of the <type>.
+
+Otherwise the raw (though uncompressed) contents of the <object> will
+be returned.
+
+
+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-check-files.txt b/Documentation/git-check-files.txt
new file mode 100644 (file)
index 0000000..6146098
--- /dev/null
@@ -0,0 +1,50 @@
+git-check-files(1)
+==================
+v0.1, May 2005
+
+NAME
+----
+git-check-files - Verify a list of files are up-to-date
+
+
+
+SYNOPSIS
+--------
+'git-check-files' <file>...
+
+DESCRIPTION
+-----------
+Check that a list of files are up-to-date between the filesystem and
+the cache. Used to verify a patch target before doing a patch.
+
+Files that do not exist on the filesystem are considered up-to-date
+(whether or not they are in the cache).
+
+Emits an error message on failure:
+
+preparing to update existing file <file> not in cache::
+         <file> exists but is not in the cache
+
+preparing to update file <file> not uptodate in cache::
+         <file> on disk is not up-to-date with the cache
+
+Exits with a status code indicating success if all files are
+up-to-date.
+
+See Also
+--------
+link:git-update-cache.html[git-update-cache]
+
+
+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-checkout-cache.txt b/Documentation/git-checkout-cache.txt
new file mode 100644 (file)
index 0000000..9d41626
--- /dev/null
@@ -0,0 +1,102 @@
+git-checkout-cache(1)
+=====================
+v0.1, May 2005
+
+NAME
+----
+git-checkout-cache - Copy files from the cache to the working directory
+
+
+SYNOPSIS
+--------
+'git-checkout-cache' [-q] [-a] [-f] [-n] [--prefix=<string>]
+                  [--] <file>...
+
+DESCRIPTION
+-----------
+Will copy all files listed from the cache to the working directory
+(not overwriting existing files).
+
+OPTIONS
+-------
+-q::
+       be quiet if files exist or are not in the cache
+
+-f::
+       forces overwrite of existing files
+
+-a::
+       checks out all files in the cache (will then continue to
+       process listed files).
+
+-n::
+       Don't checkout new files, only refresh files already checked
+       out.
+
+--prefix=<string>::
+       When creating files, prepend <string> (usually a directory
+       including a trailing /)
+
+--::
+       Do not interpret any more arguments as options.
+
+Note that the order of the flags matters:
+
+     git-checkout-cache -a -f file.c
+
+will first check out all files listed in the cache (but not overwrite
+any old ones), and then force-checkout `file.c` a second time (ie that
+one *will* overwrite any old contents with the same filename).
+
+Also, just doing "git-checkout-cache" does nothing. You probably meant
+"git-checkout-cache -a". And if you want to force it, you want
+"git-checkout-cache -f -a".
+
+Intuitiveness is not the goal here. Repeatability is. The reason for
+the "no arguments means no work" thing is that from scripts you are
+supposed to be able to do things like:
+
+       find . -name '*.h' -print0 | xargs -0 git-checkout-cache -f --
+
+which will force all existing `*.h` files to be replaced with their
+cached copies. If an empty command line implied "all", then this would
+force-refresh everything in the cache, which was not the point.
+
+To update and refresh only the files already checked out:
+
+        git-checkout-cache -n -f -a && git-update-cache --ignore-missing --refresh
+
+Oh, and the "--" is just a good idea when you know the rest will be
+filenames. Just so that you wouldn't have a filename of "-a" causing
+problems (not possible in the above example, but get used to it in
+scripting!).
+
+The prefix ability basically makes it trivial to use
+git-checkout-cache as an "export as tree" function. Just read the
+desired tree into the index, and do a
+  
+        git-checkout-cache --prefix=git-export-dir/ -a
+  
+and git-checkout-cache will "export" the cache into the specified
+directory.
+  
+NOTE The final "/" is important. The exported name is literally just
+prefixed with the specified string, so you can also do something like
+
+    git-checkout-cache --prefix=.merged- Makefile
+
+to check out the currently cached copy of `Makefile` into the file
+`.merged-Makefile`
+
+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-commit-tree.txt b/Documentation/git-commit-tree.txt
new file mode 100644 (file)
index 0000000..c0dc1f4
--- /dev/null
@@ -0,0 +1,88 @@
+git-commit-tree(1)
+==================
+v0.1, May 2005
+
+NAME
+----
+git-commit-tree - Creates a new commit object
+
+
+SYNOPSIS
+--------
+'git-commit-tree' <tree> [-p <parent commit>]\   < changelog
+
+DESCRIPTION
+-----------
+Creates a new commit object based on the provided tree object and
+emits the new commit object id on stdout. If no parent is given then
+it is considered to be an initial tree.
+
+A commit object usually has 1 parent (a commit after a change) or up
+to 16 parents.  More than one parent represents a merge of branches
+that led to them.
+
+While a tree represents a particular directory state of a working
+directory, a commit represents that state in "time", and explains how
+to get there.
+
+Normally a commit would identify 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 `.git/HEAD`, so that we can
+always see what the last committed state was.
+
+OPTIONS
+-------
+<tree>::
+       An existing tree object
+
+-p <parent commit>::
+       Each '-p' indicates a the id of a parent commit object.
+       
+
+Commit Information
+------------------
+
+A commit encapsulates:
+
+- all parent object ids
+- author name, email and date
+- committer name and email and the commit time.
+
+If not provided, "git-commit-tree" uses your name, hostname and domain to
+provide author and committer info. This can be overridden using the
+following environment variables.
+
+       GIT_AUTHOR_NAME
+       GIT_AUTHOR_EMAIL
+       GIT_AUTHOR_DATE
+       GIT_COMMITTER_NAME
+       GIT_COMMITTER_EMAIL
+
+(nb <,> and '\n's are stripped)
+
+A commit comment is read from stdin (max 999 chars). If a changelog
+entry is not provided via '<' redirection, "git-commit-tree" will just wait
+for one to be entered and terminated with ^D
+
+Diagnostics
+-----------
+You don't exist. Go away!::
+    The passwd(5) gecos field couldn't be read
+
+See Also
+--------
+link:git-write-tree.html[git-write-tree]
+
+
+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-convert-cache.txt b/Documentation/git-convert-cache.txt
new file mode 100644 (file)
index 0000000..66d7fe7
--- /dev/null
@@ -0,0 +1,30 @@
+git-convert-cache(1)
+====================
+v0.1, May 2005
+
+NAME
+----
+git-convert-cache - Converts old-style GIT repository
+
+
+SYNOPSIS
+--------
+'git-convert-cache'
+
+DESCRIPTION
+-----------
+Converts old-style GIT repository to the latest format
+
+
+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-diff-cache.txt b/Documentation/git-diff-cache.txt
new file mode 100644 (file)
index 0000000..b54b822
--- /dev/null
@@ -0,0 +1,141 @@
+git-diff-cache(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-diff-cache - Compares content and mode of blobs between the cache and repository
+
+
+SYNOPSIS
+--------
+'git-diff-cache' [-p] [-r] [-z] [-m] [--cached] <tree-ish>
+
+DESCRIPTION
+-----------
+Compares the content and mode of the blobs found via a tree object
+with the content of the current cache and, optionally ignoring the
+stat state of the file on disk.
+
+OPTIONS
+-------
+<tree-ish>::
+       The id of a tree object to diff against.
+
+-p::
+       Generate patch (see section on generating patches)
+
+-r::
+       This flag does not mean anything.  It is there only to match
+       "git-diff-tree".  Unlike "git-diff-tree", "git-diff-cache"
+       always looks at all the subdirectories.
+
+-z::
+       \0 line termination on output
+
+--cached::
+       do not consider the on-disk file at all
+
+-m::
+       By default, files recorded in the index but not checked
+       out are reported as deleted.  This flag makes
+       "git-diff-cache" say that all non-checked-out files are up
+       to date.
+
+Output format
+-------------
+include::diff-format.txt[]
+
+Operating Modes
+---------------
+You can choose whether you want to trust the index file entirely
+(using the '--cached' flag) or ask the diff logic to show any files
+that don't match the stat state as being "tentatively changed".  Both
+of these operations are very useful indeed.
+
+Cached Mode
+-----------
+If '--cached' is specified, it allows you to ask:
+
+       show me the differences between HEAD and the current index
+       contents (the ones I'd write with a "git-write-tree")
+
+For example, let's say that you have worked on your index file, and are
+ready to commit. You want to see eactly *what* you are going to commit is
+without having to write a new tree object and compare it that way, and to
+do that, you just do
+
+       git-diff-cache --cached $(cat .git/HEAD)
+
+Example: let's say I had renamed `commit.c` to `git-commit.c`, and I had
+done an "git-update-cache" to make that effective in the index file.
+"git-diff-files" wouldn't show anything at all, since the index file
+matches my working directory. But doing a "git-diff-cache" does:
+
+  torvalds@ppc970:~/git> git-diff-cache --cached $(cat .git/HEAD)
+  -100644 blob    4161aecc6700a2eb579e842af0b7f22b98443f74        commit.c
+  +100644 blob    4161aecc6700a2eb579e842af0b7f22b98443f74        git-commit.c
+
+You can trivially see that the above is a rename.
+
+In fact, "git-diff-cache --cached" *should* always be entirely equivalent to
+actually doing a "git-write-tree" and comparing that. Except this one is much
+nicer for the case where you just want to check where you are.
+
+So doing a "git-diff-cache --cached" is basically very useful when you are 
+asking yourself "what have I already marked for being committed, and 
+what's the difference to a previous tree".
+
+Non-cached Mode
+---------------
+The "non-cached" mode takes a different approach, and is potentially
+the more useful of the two in that what it does can't be emulated with
+a "git-write-tree" + "git-diff-tree". Thus that's the default mode.
+The non-cached version asks the question:
+
+   show me the differences between HEAD and the currently checked out
+   tree - index contents _and_ files that aren't up-to-date
+
+which is obviously a very useful question too, since that tells you what
+you *could* commit. Again, the output matches the "git-diff-tree -r"
+output to a tee, but with a twist.
+
+The twist is that if some file doesn't match the cache, we don't have
+a backing store thing for it, and we use the magic "all-zero" sha1 to
+show that. So let's say that you have edited `kernel/sched.c`, but
+have not actually done a "git-update-cache" on it yet - there is no
+"object" associated with the new state, and you get:
+
+  torvalds@ppc970:~/v2.6/linux> git-diff-cache $(cat .git/HEAD )
+  *100644->100664 blob    7476bb......->000000......      kernel/sched.c
+
+ie it shows that the tree has changed, and that `kernel/sched.c` has is
+not up-to-date and may contain new stuff. The all-zero sha1 means that to
+get the real diff, you need to look at the object in the working directory
+directly rather than do an object-to-object diff.
+
+NOTE! As with other commands of this type, "git-diff-cache" does not
+actually look at the contents of the file at all. So maybe
+`kernel/sched.c` hasn't actually changed, and it's just that you
+touched it. In either case, it's a note that you need to
+"git-upate-cache" it to make the cache be in sync.
+
+NOTE 2! You can have a mixture of files show up as "has been updated"
+and "is still dirty in the working directory" together. You can always
+tell which file is in which state, since the "has been updated" ones
+show a valid sha1, and the "not in sync with the index" ones will
+always have the special all-zero sha1.
+
+
+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-diff-files.txt b/Documentation/git-diff-files.txt
new file mode 100644 (file)
index 0000000..0ad2f89
--- /dev/null
@@ -0,0 +1,51 @@
+git-diff-files(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-diff-files - Compares files in the working tree and the cache
+
+
+SYNOPSIS
+--------
+'git-diff-files' [-p] [-q] [-r] [-z] [<pattern>...]
+
+DESCRIPTION
+-----------
+Compares the files in the working tree and the cache.  When paths
+are specified, compares only those named paths.  Otherwise all
+entries in the cache are compared.  The output format is the
+same as "git-diff-cache" and "git-diff-tree".
+
+OPTIONS
+-------
+-p::
+       generate patch (see section on generating patches).
+
+-q::
+       Remain silent even on nonexisting files
+
+-r::
+       This flag does not mean anything.  It is there only to match
+       git-diff-tree.  Unlike git-diff-tree, git-diff-files always looks
+       at all the subdirectories.
+
+
+Output format
+-------------
+include::diff-format.txt[]
+
+
+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-diff-tree-helper.txt b/Documentation/git-diff-tree-helper.txt
new file mode 100644 (file)
index 0000000..58f2717
--- /dev/null
@@ -0,0 +1,49 @@
+git-diff-tree-helper(1)
+=======================
+v0.1, May 2005
+
+NAME
+----
+git-diff-tree-helper - Generates patch format output for git-diff-*
+
+
+SYNOPSIS
+--------
+'git-diff-tree-helper' [-z] [-R]
+
+DESCRIPTION
+-----------
+Reads output from "git-diff-cache", "git-diff-tree" and "git-diff-files" and
+generates patch format output.
+
+OPTIONS
+-------
+-z::
+       \0 line termination on input
+
+-R::
+       Output diff in reverse.  This is useful for displaying output from
+       "git-diff-cache" which always compares tree with cache or working
+       file.  E.g.
+
+               git-diff-cache <tree> | git-diff-tree-helper -R file.c
++
+would show a diff to bring the working file back to what is in the <tree>.
+
+See Also
+--------
+The section on generating patches in link:git-diff-cache.html[git-diff-cache]
+
+
+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-diff-tree.txt b/Documentation/git-diff-tree.txt
new file mode 100644 (file)
index 0000000..ff7f25f
--- /dev/null
@@ -0,0 +1,126 @@
+git-diff-tree(1)
+================
+v0.1, May 2005
+
+NAME
+----
+git-diff-tree - Compares the content and mode of blobs found via two tree objects
+
+
+SYNOPSIS
+--------
+'git-diff-tree' [-p] [-r] [-z] [--stdin] [-m] [-s] [-v] <tree-ish> <tree-ish> [<pattern>]\*
+
+DESCRIPTION
+-----------
+Compares the content and mode of the blobs found via two tree objects.
+
+Note that "git-diff-tree" can use the tree encapsulated in a commit object.
+
+OPTIONS
+-------
+<tree-ish>::
+       The id of a tree object.
+
+<pattern>::
+       If provided, the results are limited to a subset of files
+       matching one of these prefix strings.
+       ie file matches `/^<pattern1>|<pattern2>|.../`
+       Note that pattern does not provide any wildcard or regexp
+       features.
+
+-p::
+       generate patch (see section on generating patches).  For
+       git-diff-tree, this flag implies '-r' as well.
+
+-r::
+       recurse
+
+-z::
+       \0 line termination on output
+
+--stdin::
+       When '--stdin' is specified, the command does not take
+       <tree-ish> arguments from the command line.  Instead, it
+       reads either one <commit> or a pair of <tree-ish>
+       separated with a single space from its standard input.
++
+When a single commit is given on one line of such input, it compares
+the commit with its parents.  The following flags further affects its
+behaviour.  This does not apply to the case where two <tree-ish>
+separated with a single space are given.
+
+-m::
+       By default, "git-diff-tree --stdin" does not show
+       differences for merge commits.  With this flag, it shows
+       differences to that commit from all of its parents.
+
+-s::
+       By default, "git-diff-tree --stdin" shows differences,
+       either in machine-readable form (without '-p') or in patch
+       form (with '-p').  This output can be supressed.  It is
+       only useful with '-v' flag.
+
+-v::
+       This flag causes "git-diff-tree --stdin" to also show
+       the commit message before the differences.
+
+
+Limiting Output
+---------------
+If you're only interested in differences in a subset of files, for
+example some architecture-specific files, you might do:
+
+       git-diff-tree -r <tree-ish> <tree-ish> arch/ia64 include/asm-ia64
+
+and it will only show you what changed in those two directories.
+
+Or if you are searching for what changed in just `kernel/sched.c`, just do
+
+       git-diff-tree -r <tree-ish> <tree-ish> kernel/sched.c
+
+and it will ignore all differences to other files.
+
+The pattern is always the prefix, and is matched exactly.  There are no
+wildcards.  Even stricter, it has to match complete path comonent.
+I.e. "foo" does not pick up `foobar.h`.  "foo" does match `foo/bar.h`
+so it can be used to name subdirectories.
+
+An example of normal usage is:
+
+  torvalds@ppc970:~/git> git-diff-tree 5319e4......
+  *100664->100664 blob    ac348b.......->a01513.......      git-fsck-cache.c
+
+which tells you that the last commit changed just one file (it's from
+this one:
+
+  commit 3c6f7ca19ad4043e9e72fa94106f352897e651a8
+  tree 5319e4d609cdd282069cc4dce33c1db559539b03
+  parent b4e628ea30d5ab3606119d2ea5caeab141d38df7
+  author Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
+  committer Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
+
+  Make "git-fsck-cache" print out all the root commits it finds.
+
+  Once I do the reference tracking, I'll also make it print out all the
+  HEAD commits it finds, which is even more interesting.
+
+in case you care).
+
+Output format
+-------------
+include::diff-format.txt[]
+
+
+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-export.txt b/Documentation/git-export.txt
new file mode 100644 (file)
index 0000000..d2d0dc4
--- /dev/null
@@ -0,0 +1,31 @@
+git-export(1)
+=============
+v0.1, May 2005
+
+NAME
+----
+git-export - Exports each commit and a diff against each of its parents
+
+
+SYNOPSIS
+--------
+'git-export' top [base]
+
+DESCRIPTION
+-----------
+Exports each commit and diff against each of its parents, between
+top and base.  If base is not specified it exports everything.
+
+
+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-fsck-cache.txt b/Documentation/git-fsck-cache.txt
new file mode 100644 (file)
index 0000000..bcd3b0a
--- /dev/null
@@ -0,0 +1,122 @@
+git-fsck-cache(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-fsck-cache - Verifies the connectivity and validity of the objects in the database
+
+
+SYNOPSIS
+--------
+'git-fsck-cache' [--tags] [--root] [[--unreachable] [--cache] <object>\*]
+
+DESCRIPTION
+-----------
+Verifies the connectivity and validity of the objects in the database.
+
+OPTIONS
+-------
+<object>::
+       An object to treat as the head of an unreachability trace.
+
+--unreachable::
+       Print out objects that exist but that aren't readable from any
+       of the specified head nodes.
+
+--root::
+       Report root nodes.
+
+--tags::
+       Report tags.
+
+--cache::
+       Consider any object recorded in the cache also as a head node for
+       an unreachability trace.
+
+It tests SHA1 and general object sanity, and it does full tracking of
+the resulting reachability and everything else. It prints out any
+corruption it finds (missing or bad objects), and if you use the
+'--unreachable' flag it will also print out objects that exist but
+that aren't readable from any of the specified head nodes.
+
+So for example
+
+       git-fsck-cache --unreachable $(cat .git/HEAD)
+
+or, for Cogito users:
+
+       git-fsck-cache --unreachable $(cat .git/refs/heads/*)
+
+will do quite a _lot_ of verification on the tree. There are a few
+extra validity tests to be added (make sure that tree objects are
+sorted properly etc), but on the whole if "git-fsck-cache" is happy, you
+do have a valid tree.
+
+Any corrupt objects you will have to find in backups or other archives
+(ie you can just remove them and do an "rsync" with some other site in
+the hopes that somebody else has the object you have corrupted).
+
+Of course, "valid tree" doesn't mean that it wasn't generated by some
+evil person, and the end result might be crap. Git is a revision
+tracking system, not a quality assurance system ;)
+
+Extracted Diagnostics
+---------------------
+
+expect dangling commits - potential heads - due to lack of head information::
+       You haven't specified any nodes as heads so it won't be
+       possible to differentiate between un-parented commits and
+       root nodes.
+
+missing sha1 directory '<dir>'::
+       The directory holding the sha1 objects is missing.
+
+unreachable <type> <object>::
+       The <type> object <object>, isn't actually referred to directly
+       or indirectly in any of the trees or commits seen. This can
+       mean that there's another root node that you're not specifying
+       or that the tree is corrupt. If you haven't missed a root node
+       then you might as well delete unreachable nodes since they
+       can't be used.
+
+missing <type> <object>::
+       The <type> object <object>, is referred to but isn't present in
+       the database.
+
+dangling <type> <object>::
+       The <type> object <object>, is present in the database but never
+       'directly' used. A dangling commit could be a root node.
+
+warning: git-fsck-cache: tree <tree> has full pathnames in it::
+       And it shouldn't...
+
+sha1 mismatch <object>::
+       The database has an object who's sha1 doesn't match the
+       database value.
+       This indicates a serious data integrity problem.
+       (note: this error occured during early git development when
+       the database format changed.)
+
+Environment Variables
+---------------------
+
+GIT_OBJECT_DIRECTORY::
+       used to specify the object database root (usually .git/objects)
+
+GIT_INDEX_FILE::
+       used to specify the cache
+
+
+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-http-pull.txt b/Documentation/git-http-pull.txt
new file mode 100644 (file)
index 0000000..59cd090
--- /dev/null
@@ -0,0 +1,39 @@
+git-http-pull(1)
+================
+v0.1, May 2005
+
+NAME
+----
+git-http-pull - Downloads a remote GIT repository via HTTP
+
+
+SYNOPSIS
+--------
+'git-http-pull' [-c] [-t] [-a] [-v] commit-id url
+
+DESCRIPTION
+-----------
+Downloads a remote GIT repository via HTTP.
+
+-c::
+       Get the commit objects.
+-t::
+       Get trees associated with the commit objects.
+-a::
+       Get all the objects.
+-v::
+       Report what is downloaded.
+
+
+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-init-db.txt b/Documentation/git-init-db.txt
new file mode 100644 (file)
index 0000000..99f96f7
--- /dev/null
@@ -0,0 +1,40 @@
+git-init-db(1)
+==============
+v0.1, May 2005
+
+NAME
+----
+git-init-db - Creates an empty git object database
+
+
+SYNOPSIS
+--------
+'git-init-db'
+
+DESCRIPTION
+-----------
+This simply creates an empty git object database - basically a `.git`
+directory and `.git/object/??/` directories.
+
+If the 'GIT_DIR' environment variable is set then it specifies a path
+to use instead of `./.git` for the base of the repository.
+
+If the object storage directory is specified via the 'GIT_OBJECT_DIRECTORY'
+environment variable then the sha1 directories are created underneath -
+otherwise the default `.git/objects` directory is used.
+
+"git-init-db" won't hurt an existing repository.
+
+
+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-local-pull.txt b/Documentation/git-local-pull.txt
new file mode 100644 (file)
index 0000000..53f5d39
--- /dev/null
@@ -0,0 +1,40 @@
+git-local-pull(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-local-pull - Duplicates another GIT repository on a local system
+
+
+SYNOPSIS
+--------
+'git-local-pull' [-c] [-t] [-a] [-l] [-s] [-n] [-v] commit-id path
+
+DESCRIPTION
+-----------
+Duplicates another GIT repository on a local system.
+
+OPTIONS
+-------
+-c::
+       Get the commit objects.
+-t::
+       Get trees associated with the commit objects.
+-a::
+       Get all the objects.
+-v::
+       Report what is downloaded.
+
+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-ls-files.txt b/Documentation/git-ls-files.txt
new file mode 100644 (file)
index 0000000..14ca695
--- /dev/null
@@ -0,0 +1,102 @@
+git-ls-files(1)
+===============
+v0.1, May 2005
+
+NAME
+----
+git-ls-files - Information about files in the cache/working directory
+
+
+SYNOPSIS
+--------
+'git-ls-files' [-z] [-t]
+               (--[cached|deleted|others|ignored|stage|unmerged])\*
+               (-[c|d|o|i|s|u])\*
+               [-x <pattern>|--exclude=<pattern>]
+               [-X <file>|--exclude-from=<file>]
+
+DESCRIPTION
+-----------
+This merges the file listing in the directory cache index with the
+actual working directory list, and shows different combinations of the
+two.
+
+One or more of the options below may be used to determine the files
+shown:
+
+OPTIONS
+-------
+-c|--cached::
+       Show cached files in the output (default)
+
+-d|--deleted::
+       Show deleted files in the output
+
+-o|--others::
+       Show other files in the output
+
+-i|--ignored::
+       Show ignored files in the output
+       Note the this also reverses any exclude list present.
+
+-s|--stage::
+       Show stage files in the output
+
+-u|--unmerged::
+       Show unmerged files in the output (forces --stage)
+
+-z::
+       \0 line termination on output
+
+-x|--exclude=<pattern>::
+       Skips files matching pattern.
+       Note that pattern is a shell wildcard pattern.
+
+-X|--exclude-from=<file>::
+       exclude patterns are read from <file>; 1 per line.
+       Allows the use of the famous dontdiff file as follows to find
+       out about uncommitted files just as dontdiff is used with
+       the diff command:
+            git-ls-files --others --exclude-from=dontdiff
+
+-t::
+       Identify the file status with the following tags (followed by
+       a space) at the start of each line:
+       H       cached
+       M       unmerged
+       R       removed/deleted
+       ?       other
+
+Output
+------
+show files just outputs the filename unless '--stage' is specified in
+which case it outputs:
+
+        [<tag> ]<mode> <object> <stage> <file>
+
+"git-ls-files --unmerged" and "git-ls-files --stage" can be used to examine
+detailed information on unmerged paths.
+
+For an unmerged path, instead of recording a single mode/SHA1 pair,
+the dircache records up to three such pairs; one from tree O in stage
+1, A in stage 2, and B in stage 3.  This information can be used by
+the user (or Cogito) to see what should eventually be recorded at the
+path. (see read-cache for more information on state)
+
+See Also
+--------
+link:read-cache.html[read-cache]
+
+
+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-ls-tree.txt b/Documentation/git-ls-tree.txt
new file mode 100644 (file)
index 0000000..f6e15ad
--- /dev/null
@@ -0,0 +1,46 @@
+git-ls-tree(1)
+==============
+v0.1, May 2005
+
+NAME
+----
+git-ls-tree - Displays a tree object in human readable form
+
+
+SYNOPSIS
+--------
+'git-ls-tree' [-r] [-z] <tree-ish>
+
+DESCRIPTION
+-----------
+Converts the tree object to a human readable (and script processable)
+form.
+
+OPTIONS
+-------
+<tree-ish>::
+       Id of a tree.
+
+-r::
+       recurse into sub-trees
+
+-z::
+       \0 line termination on output
+
+Output Format
+-------------
+        <mode>\t       <type>\t        <object>\t      <file>
+
+
+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-base.txt b/Documentation/git-merge-base.txt
new file mode 100644 (file)
index 0000000..1e27bf2
--- /dev/null
@@ -0,0 +1,34 @@
+git-merge-base(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-merge-base - Finds as good a common ancestor as possible for a merge
+
+
+SYNOPSIS
+--------
+'git-merge-base' <commit> <commit>
+
+DESCRIPTION
+-----------
+"git-merge-base" finds as good a common ancestor as possible. Given a
+selection of equally good common ancestors it should not be relied on
+to decide in any particular way.
+
+The "git-merge-base" algorithm is still in flux - use the source...
+
+
+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-cache.txt b/Documentation/git-merge-cache.txt
new file mode 100644 (file)
index 0000000..343607c
--- /dev/null
@@ -0,0 +1,77 @@
+git-merge-cache(1)
+==================
+v0.1, May 2005
+
+NAME
+----
+git-merge-cache - Runs a merge for files needing merging
+
+
+SYNOPSIS
+--------
+'git-merge-cache' <merge-program> (-a | -- | <file>\*) 
+
+DESCRIPTION
+-----------
+This looks up the <file>(s) in the cache and, if there are any merge
+entries, passes the SHA1 hash for those files as arguments 1, 2, 3 (empty
+argument if no file), and <file> as argument 4.  File modes for the three
+files are passed as arguments 5, 6 and 7.
+
+OPTIONS
+-------
+--::
+       Interpret all future arguments as filenames.
+
+-a::
+       Run merge against all files in the cache that need merging.
+
+If "git-merge-cache" is called with multiple <file>s (or -a) then it
+processes them in turn only stopping if merge returns a non-zero exit
+code.
+
+Typically this is run with the a script calling the merge command from
+the RCS package.
+
+A sample script called "git-merge-one-file-script" is included in the
+ditribution.
+
+ALERT ALERT ALERT! The git "merge object order" is different from the
+RCS "merge" program merge object order. In the above ordering, the
+original is first. But the argument order to the 3-way merge program
+"merge" is to have the original in the middle. Don't ask me why.
+
+Examples:
+
+  torvalds@ppc970:~/merge-test> git-merge-cache cat MM
+  This is MM from the original tree.                   # original
+  This is modified MM in the branch A.                 # merge1
+  This is modified MM in the branch B.                 # merge2
+  This is modified MM in the branch B.                 # current contents
+
+or 
+
+  torvalds@ppc970:~/merge-test> git-merge-cache cat AA MM
+  cat: : No such file or directory
+  This is added AA in the branch A.
+  This is added AA in the branch B.
+  This is added AA in the branch B.
+  fatal: merge program failed
+
+where the latter example shows how "git-merge-cache" will stop trying to
+merge once anything has returned an error (ie "cat" returned an error
+for the AA file, because it didn't exist in the original, and thus
+"git-merge-cache" didn't even try to merge the MM thing).
+
+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
new file mode 100644 (file)
index 0000000..387601d
--- /dev/null
@@ -0,0 +1,30 @@
+git-merge-one-file-script(1)
+============================
+v0.1, May 2005
+
+NAME
+----
+git-merge-one-file-script - The standard helper program to use with "git-merge-cache"
+
+
+SYNOPSIS
+--------
+'git-merge-one-file-script'
+
+DESCRIPTION
+-----------
+This is the standard helper program to use with "git-merge-cache"
+to resolve a merge after the trivial merge done with "git-read-tree -m".
+
+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-mktag.txt b/Documentation/git-mktag.txt
new file mode 100644 (file)
index 0000000..708f4ef
--- /dev/null
@@ -0,0 +1,48 @@
+git-mktag(1)
+============
+v0.1, May 2005
+
+NAME
+----
+git-mktag - Creates a tag object
+
+
+SYNOPSIS
+--------
+'git-mktag' < signature_file
+
+DESCRIPTION
+-----------
+Reads a tag contents on standard input and creates a tag object
+that can also be used to sign other objects.
+
+The output is the new tag's <object> identifier.
+
+Tag Format
+----------
+A tag signature file has a very simple fixed format: three lines of
+
+  object <sha1>
+  type <typename>
+  tag <tagname>
+
+followed by some 'optional' free-form signature that git itself
+doesn't care about, but that can be verified with gpg or similar.
+
+The size of the full object is artificially limited to 8kB.  (Just
+because I'm a lazy bastard, and if you can't fit a signature in that
+size, you're doing something wrong)
+
+
+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-prune-script.txt b/Documentation/git-prune-script.txt
new file mode 100644 (file)
index 0000000..537b790
--- /dev/null
@@ -0,0 +1,32 @@
+git-prune-script(1)
+===================
+v0.1, May 2005
+
+NAME
+----
+git-prune-script - Prunes all unreachable objects from the object database
+
+
+SYNOPSIS
+--------
+'git-prune-script'
+
+DESCRIPTION
+-----------
+This runs "git-fsck-cache --unreachable" program using the heads specified
+on the command line (or `.git/refs/heads/\*` and `.git/refs/tags/\*` if none is
+specified), and prunes all unreachable objects from the object database.
+
+
+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-pull-script.txt b/Documentation/git-pull-script.txt
new file mode 100644 (file)
index 0000000..44fd09a
--- /dev/null
@@ -0,0 +1,31 @@
+git-pull-script(1)
+==================
+v0.1, May 2005
+
+NAME
+----
+git-pull-script - Script used by Linus to pull and merge a remote repository
+
+
+SYNOPSIS
+--------
+'git-pull-script'
+
+DESCRIPTION
+-----------
+This script is used by Linus to pull from a remote repository and perform
+a merge.
+
+
+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-read-tree.txt b/Documentation/git-read-tree.txt
new file mode 100644 (file)
index 0000000..cbde13d
--- /dev/null
@@ -0,0 +1,152 @@
+git-read-tree(1)
+================
+v0.1, May 2005
+
+NAME
+----
+git-read-tree - Reads tree information into the directory cache
+
+
+SYNOPSIS
+--------
+'git-read-tree' (<tree-ish> | -m <tree-ish1> [<tree-ish2> <tree-ish3>])"
+
+DESCRIPTION
+-----------
+Reads the tree information given by <tree> into the directory cache,
+but does not actually *update* any of the files it "caches". (see:
+git-checkout-cache)
+
+Optionally, it can merge a tree into the cache or perform a 3-way
+merge.
+
+Trivial merges are done by "git-read-tree" itself.  Only conflicting paths
+will be in unmerged state when "git-read-tree" returns.
+
+OPTIONS
+-------
+-m::
+       Perform a merge, not just a read
+
+<tree-ish#>::
+       The id of the tree object(s) to be read/merged.
+
+
+Merging
+-------
+If '-m' is specified, "git-read-tree" performs 2 kinds of merge, a single tree
+merge if only 1 tree is given or a 3-way merge if 3 trees are
+provided.
+
+Single Tree Merge
+~~~~~~~~~~~~~~~~~
+If only 1 tree is specified, git-read-tree operates as if the user did not
+specify '-m', except that if the original cache has an entry for a
+given pathname; and the contents of the path matches with the tree
+being read, the stat info from the cache is used. (In other words, the
+cache's stat()s take precedence over the merged tree's)
+
+That means that if you do a "git-read-tree -m <newtree>" followed by a
+"git-checkout-cache -f -a", the "git-checkout-cache" only checks out
+the stuff that really changed.
+
+This is used to avoid unnecessary false hits when "git-diff-files" is
+run after git-read-tree.
+
+3-Way Merge
+~~~~~~~~~~~
+Each "index" entry has two bits worth of "stage" state. stage 0 is the
+normal one, and is the only one you'd see in any kind of normal use.
+
+However, when you do "git-read-tree" with three trees, the "stage"
+starts out at 1.
+
+This means that you can do
+
+       git-read-tree -m <tree1> <tree2> <tree3>
+
+and you will end up with an index with all of the <tree1> entries in
+"stage1", all of the <tree2> entries in "stage2" and all of the
+<tree3> entries in "stage3".
+
+Furthermore, "git-read-tree" has special-case logic that says: if you see
+a file that matches in all respects in the following states, it
+"collapses" back to "stage0":
+
+   - stage 2 and 3 are the same; take one or the other (it makes no
+     difference - the same work has been done on stage 2 and 3)
+
+   - stage 1 and stage 2 are the same and stage 3 is different; take
+     stage 3 (some work has been done on stage 3)
+
+   - stage 1 and stage 3 are the same and stage 2 is different take
+     stage 2 (some work has been done on stage 2)
+
+The "git-write-tree" command refuses to write a nonsensical tree, and it
+will complain about unmerged entries if it sees a single entry that is not
+stage 0.
+
+Ok, this all sounds like a collection of totally nonsensical rules,
+but it's actually exactly what you want in order to do a fast
+merge. The different stages represent the "result tree" (stage 0, aka
+"merged"), the original tree (stage 1, aka "orig"), and the two trees
+you are trying to merge (stage 2 and 3 respectively).
+
+In fact, the way "git-read-tree" works, it's entirely agnostic about how
+you assign the stages, and you could really assign them any which way,
+and the above is just a suggested way to do it (except since
+"git-write-tree" refuses to write anything but stage0 entries, it makes
+sense to always consider stage 0 to be the "full merge" state).
+
+So what happens? Try it out. Select the original tree, and two trees
+to merge, and look how it works:
+
+- if a file exists in identical format in all three trees, it will
+  automatically collapse to "merged" state by the new git-read-tree.
+
+- a file that has _any_ difference what-so-ever in the three trees
+  will stay as separate entries in the index. It's up to "script
+  policy" to determine how to remove the non-0 stages, and insert a
+  merged version.  But since the index is always sorted, they're easy
+  to find: they'll be clustered together.
+
+- the index file saves and restores with all this information, so you
+  can merge things incrementally, but as long as it has entries in
+  stages 1/2/3 (ie "unmerged entries") you can't write the result. So
+  now the merge algorithm ends up being really simple:
+
+  * you walk the index in order, and ignore all entries of stage 0,
+    since they've already been done.
+
+  * if you find a "stage1", but no matching "stage2" or "stage3", you
+    know it's been removed from both trees (it only existed in the
+    original tree), and you remove that entry.
+
+  * if you find a matching "stage2" and "stage3" tree, you remove one
+    of them, and turn the other into a "stage0" entry. Remove any
+    matching "stage1" entry if it exists too.  .. all the normal
+    trivial rules ..
+
+Incidentally - it also means that you don't even have to have a
+separate subdirectory for this. All the information literally is in
+the index file, which is a temporary thing anyway. There is no need to
+worry about what is in the working directory, since it is never shown
+and never used.
+
+See Also
+--------
+link:git-write-tree.html[git-write-tree]; link:git-ls-files.html[git-ls-files]
+
+
+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-resolve-script.txt b/Documentation/git-resolve-script.txt
new file mode 100644 (file)
index 0000000..8dd84a3
--- /dev/null
@@ -0,0 +1,30 @@
+git-resolve-script(1)
+=====================
+v0.1, May 2005
+
+NAME
+----
+git-resolve-script - Script used to merge two trees
+
+
+SYNOPSIS
+--------
+'git-resolve-script'
+
+DESCRIPTION
+-----------
+This script is used by Linus to merge two trees.
+
+
+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-rev-list.txt b/Documentation/git-rev-list.txt
new file mode 100644 (file)
index 0000000..f2c5fa9
--- /dev/null
@@ -0,0 +1,32 @@
+git-rev-list(1)
+===============
+v0.1, May 2005
+
+NAME
+----
+git-rev-list - Lists commit objects in reverse chronological order
+
+
+SYNOPSIS
+--------
+'git-rev-list' <commit>
+
+DESCRIPTION
+-----------
+Lists commit objects in reverse chronological order starting at the
+given commit, taking ancestry relationship into account.  This is
+useful to produce human-readable log output.
+
+
+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-rev-tree.txt b/Documentation/git-rev-tree.txt
new file mode 100644 (file)
index 0000000..2ec7ed0
--- /dev/null
@@ -0,0 +1,88 @@
+git-rev-tree(1)
+===============
+v0.1, May 2005
+
+NAME
+----
+git-rev-tree - Provides the revision tree for one or more commits
+
+
+SYNOPSIS
+--------
+'git-rev-tree' [--edges] [--cache <cache-file>] [^]<commit> [[^]<commit>]
+
+DESCRIPTION
+-----------
+Provides the revision tree for one or more commits.
+
+OPTIONS
+-------
+--edges::
+       Show edges (ie places where the marking changes between parent
+       and child)
+
+--cache <cache-file>::
+       Use the specified file as a cache from a previous git-rev-list run
+       to speed things up.  Note that this "cache" is totally different
+       concept from the directory index.  Also this option is not
+       implemented yet.
+
+[^]<commit>::
+       The commit id to trace (a leading caret means to ignore this
+       commit-id and below)
+
+Output
+------
+
+        <date> <commit>:<flags> [<parent-commit>:<flags> ]\*
+
+<date>::
+       Date in 'seconds since epoch'
+
+<commit>::
+       id of commit object
+
+<parent-commit>::
+       id of each parent commit object (>1 indicates a merge)
+
+<flags>::
+
+       The flags are read as a bitmask representing each commit
+       provided on the commandline. eg: given the command:
+
+                $ git-rev-tree <com1> <com2> <com3>
+
+       The output:
+
+           <date> <commit>:5
+
+        means that <commit> is reachable from <com1>(1) and <com3>(4)
+       
+A revtree can get quite large. "git-rev-tree" will eventually allow
+you to cache previous state so that you don't have to follow the whole
+thing down.
+
+So the change difference between two commits is literally
+
+       git-rev-tree [commit-id1]  > commit1-revtree
+       git-rev-tree [commit-id2]  > commit2-revtree
+       join -t : commit1-revtree commit2-revtree > common-revisions
+
+(this is also how to find the most common parent - you'd look at just
+the head revisions - the ones that aren't referred to by other
+revisions - in "common-revision", and figure out the best one. I
+think.)
+
+
+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-rpull.txt b/Documentation/git-rpull.txt
new file mode 100644 (file)
index 0000000..1807fc5
--- /dev/null
@@ -0,0 +1,43 @@
+git-rpull(1)
+============
+v0.1, May 2005
+
+NAME
+----
+git-rpull - Pulls from a remote repository over ssh connection
+
+
+
+SYNOPSIS
+--------
+'git-rpull' [-c] [-t] [-a] [-v] commit-id url
+
+DESCRIPTION
+-----------
+Pulls from a remote repository over ssh connection, invoking git-rpush on
+the other end.
+
+OPTIONS
+-------
+-c::
+       Get the commit objects.
+-t::
+       Get trees associated with the commit objects.
+-a::
+       Get all the objects.
+-v::
+       Report what is downloaded.
+
+
+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-rpush.txt b/Documentation/git-rpush.txt
new file mode 100644 (file)
index 0000000..1c1cbab
--- /dev/null
@@ -0,0 +1,30 @@
+git-rpush(1)
+============
+v0.1, May 2005
+
+NAME
+----
+git-rpush - Helper "server-side" program used by git-rpull
+
+
+SYNOPSIS
+--------
+'git-rpush'
+
+DESCRIPTION
+-----------
+Helper "server-side" program used by git-rpull.
+
+
+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-tag-script.txt b/Documentation/git-tag-script.txt
new file mode 100644 (file)
index 0000000..daf350b
--- /dev/null
@@ -0,0 +1,32 @@
+git-tag-script(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-tag-script - An example script to create a tag object signed with GPG
+
+
+
+SYNOPSIS
+--------
+'git-tag-script'
+
+DESCRIPTION
+-----------
+This is an example script that uses "git-mktag" to create a tag object
+signed with GPG.
+
+
+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-tar-tree.txt b/Documentation/git-tar-tree.txt
new file mode 100644 (file)
index 0000000..7870e92
--- /dev/null
@@ -0,0 +1,32 @@
+git-tar-tree(1)
+===============
+v0.1, May 2005
+
+NAME
+----
+git-tar-tree - Creates a tar archive of the files in the named tree
+
+
+SYNOPSIS
+--------
+'git-tar-tree' <tree-ish> [ <base> ]
+
+DESCRIPTION
+-----------
+Creates a tar archive containing the tree structure for the named tree.
+When <base> is specified it is added as a leading path as the files in the
+generated tar archive.
+
+
+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-unpack-file.txt b/Documentation/git-unpack-file.txt
new file mode 100644 (file)
index 0000000..2f2130d
--- /dev/null
@@ -0,0 +1,37 @@
+git-unpack-file(1)
+==================
+v0.1, May 2005
+
+NAME
+----
+git-unpack-file - Creates a temporary file with a blob's contents
+
+
+
+SYNOPSIS
+--------
+'git-unpack-file' <blob>
+
+DESCRIPTION
+-----------
+Creates a file holding the contents of the blob specified by sha1. It
+returns the name of the temporary file in the following format:
+       .merge_file_XXXXX
+
+OPTIONS
+-------
+<blob>::
+       Must be a blob id
+
+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-update-cache.txt b/Documentation/git-update-cache.txt
new file mode 100644 (file)
index 0000000..604411d
--- /dev/null
@@ -0,0 +1,108 @@
+git-update-cache(1)
+===================
+v0.1, May 2005
+
+NAME
+----
+git-update-cache - Modifies the index or directory cache
+
+
+SYNOPSIS
+--------
+'git-update-cache'
+            [--add] [--remove] [--refresh] [--replace]
+            [--ignore-missing]
+            [--force-remove <file>]
+            [--cacheinfo <mode> <object> <file>]\*
+            [--] [<file>]\*
+
+DESCRIPTION
+-----------
+Modifies the index or directory cache. Each file mentioned is updated
+into the cache and any 'unmerged' or 'needs updating' state is
+cleared.
+
+The way "git-update-cache" handles files it is told about can be modified
+using the various options:
+
+OPTIONS
+-------
+--add::
+       If a specified file isn't in the cache already then it's
+       added.
+       Default behaviour is to ignore new files.
+
+--remove::
+       If a specified file is in the cache but is missing then it's
+       removed.
+       Default behaviour is to ignore removed file.
+
+--refresh::
+       Looks at the current cache and checks to see if merges or
+       updates are needed by checking stat() information.
+
+--ignore-missing::
+       Ignores missing files during a --refresh
+
+--cacheinfo <mode> <object> <path>::
+       Directly insert the specified info into the cache.
+       
+--force-remove::
+       Remove the file from the index even when the working directory
+       still has such a file.
+
+--replace::
+       By default, when a file `path` exists in the index,
+       git-update-cache refuses an attempt to add `path/file`.
+       Similarly if a file `path/file` exists, a file `path`
+       cannot be added.  With --replace flag, existing entries
+       that conflicts with the entry being added are
+       automatically removed with warning messages.
+
+--::
+       Do not interpret any more arguments as options.
+
+<file>::
+       Files to act on.
+       Note that files begining with '.' are discarded. This includes
+       `./file` and `dir/./file`. If you don't want this, then use     
+       cleaner names.
+       The same applies to directories ending '/' and paths with '//'
+
+Using --refresh
+---------------
+'--refresh' does not calculate a new sha1 file or bring the cache
+up-to-date for mode/content changes. But what it *does* do is to
+"re-match" the stat information of a file with the cache, so that you
+can refresh the cache for a file that hasn't been changed but where
+the stat entry is out of date.
+
+For example, you'd want to do this after doing a "git-read-tree", to link
+up the stat cache details with the proper files.
+
+Using --cacheinfo
+-----------------
+'--cacheinfo' is used to register a file that is not in the current
+working directory.  This is useful for minimum-checkout merging.
+
+To pretend you have a file with mode and sha1 at path, say:
+
+ $ git-update-cache --cacheinfo mode sha1 path
+
+To update and refresh only the files already checked out:
+
+   git-checkout-cache -n -f -a && git-update-cache --ignore-missing --refresh
+
+
+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-write-blob.txt b/Documentation/git-write-blob.txt
new file mode 100644 (file)
index 0000000..22d7555
--- /dev/null
@@ -0,0 +1,33 @@
+git-write-blob(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-write-blob - Creates a blob from a file
+
+
+SYNOPSIS
+--------
+'git-write-blob' <any-file-on-the-filesystem>
+
+DESCRIPTION
+-----------
+Writes the contents of the named file (which can be outside of the work
+tree) as a blob into the object database, and reports its object ID to its
+standard output.  This is used by "git-merge-one-file-script" to update the
+cache without modifying files in the work tree.
+
+
+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-write-tree.txt b/Documentation/git-write-tree.txt
new file mode 100644 (file)
index 0000000..458d97a
--- /dev/null
@@ -0,0 +1,52 @@
+git-write-tree(1)
+=================
+v0.1, May 2005
+
+NAME
+----
+git-write-tree - Creates a tree from the current cache
+
+
+SYNOPSIS
+--------
+'git-write-tree'
+
+DESCRIPTION
+-----------
+Creates a tree object using the current cache.
+
+The cache must be merged.
+
+Conceptually, "git-write-tree" sync()s the current directory cache contents
+into a set of tree files.
+In order to have that match what is actually in your directory right
+now, you need to have done a "git-update-cache" phase before you did the
+"git-write-tree".
+
+
+
+
+////////////////////////////////////////////////////////////////
+
+Producing man pages and html
+
+To create a set of html pages run:
+  perl split-docs.pl -html < core-git.txt
+
+To create a set of man pages run:
+  perl split-docs.pl -man < core-git.txt
+
+
+////////////////////////////////////////////////////////////////
+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.txt b/Documentation/git.txt
new file mode 100644 (file)
index 0000000..a02ed6f
--- /dev/null
@@ -0,0 +1,309 @@
+git(1)
+======
+v0.1, May 2005
+
+NAME
+----
+git - the stupid content tracker
+
+
+SYNOPSIS
+--------
+'git-<command>' <args>
+
+DESCRIPTION
+-----------
+
+This is reference information for the core git commands.
+
+The link:README[] contains much useful definition and clarification
+info - read that first.  And of the commands, I suggest reading
+'git-update-cache' and 'git-read-tree' first - I wish I had!
+
+David Greaves <david@dgreaves.com>
+08/05/05
+
+Updated by Junio C Hamano <junkio@cox.net> on 2005-05-05 to
+reflect recent changes.
+
+Commands Overview
+-----------------
+The git commands can helpfully be split into those that manipulate
+the repository, the cache and the working fileset and those that
+interrogate and compare them.
+
+There are also some ancilliary 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.
+
+Manipulation commands
+~~~~~~~~~~~~~~~~~~~~~
+link:git-checkout-cache.html[git-checkout-cache]::
+       Copy files from the cache to the working directory
+
+link:git-commit-tree.html[git-commit-tree]::
+       Creates a new commit object
+
+link:git-init-db.html[git-init-db]::
+       Creates an empty git object database
+
+link:git-merge-base.html[git-merge-base]::
+       Finds as good a common ancestor as possible for a merge
+
+link:git-mktag.html[git-mktag]::
+       Creates a tag object
+
+link:git-read-tree.html[git-read-tree]::
+       Reads tree information into the directory cache
+
+link:git-update-cache.html[git-update-cache]::
+       Modifies the index or directory cache
+
+link:git-write-blob.html[git-write-blob]::
+       Creates a blob from a file
+
+link:git-write-tree.html[git-write-tree]::
+       Creates a tree from the current cache
+
+Interrogation commands
+~~~~~~~~~~~~~~~~~~~~~~
+link:git-cat-file.html[git-cat-file]::
+       Provide content or type information for repository objects
+
+link:git-check-files.html[git-check-files]::
+       Verify a list of files are up-to-date
+
+link:git-diff-cache.html[git-diff-cache]::
+       Compares content and mode of blobs between the cache and repository
+
+link:git-diff-files.html[git-diff-files]::
+       Compares files in the working tree and the cache
+
+link:git-diff-tree.html[git-diff-tree]::
+       Compares the content and mode of blobs found via two tree objects
+
+link:git-export.html[git-export]::
+       Exports each commit and a diff against each of its parents
+
+link:git-fsck-cache.html[git-fsck-cache]::
+       Verifies the connectivity and validity of the objects in the database
+
+link:git-ls-files.html[git-ls-files]::
+       Information about files in the cache/working directory
+
+link:git-ls-tree.html[git-ls-tree]::
+       Displays a tree object in human readable form
+
+link:git-merge-cache.html[git-merge-cache]::
+       Runs a merge for files needing merging
+
+link:git-rev-list.html[git-rev-list]::
+       Lists commit objects in reverse chronological order
+
+link:git-rev-tree.html[git-rev-tree]::
+       Provides the revision tree for one or more commits
+
+link:git-tar-tree.html[git-tar-tree]::
+       Creates a tar archive of the files in the named tree
+
+link:git-unpack-file.html[git-unpack-file]::
+       Creates a temporary file with a blob's contents
+
+The interrogate commands may create files - and you can force them to
+touch the working file set - but in general they don't
+
+
+Ancilliary Commands
+-------------------
+Manipulators:
+
+link:git-apply-patch-script.html[git-apply-patch-script]::
+       Sample script to apply the diffs from git-diff-*
+
+link:git-convert-cache.html[git-convert-cache]::
+       Converts old-style GIT repository
+
+link:git-http-pull.html[git-http-pull]::
+       Downloads a remote GIT repository via HTTP
+
+link:git-local-pull.html[git-local-pull]::
+       Duplicates another GIT repository on a local system
+
+link:git-merge-one-file-script.html[git-merge-one-file-script]::
+       The standard helper program to use with "git-merge-cache"
+
+link:git-pull-script.html[git-pull-script]::
+       Script used by Linus to pull and merge a remote repository
+
+link:git-prune-script.html[git-prune-script]::
+       Prunes all unreachable objects from the object database
+
+link:git-resolve-script.html[git-resolve-script]::
+       Script used to merge two trees
+
+link:git-tag-script.html[git-tag-script]::
+       An example script to create a tag object signed with GPG
+
+link:git-rpull.html[git-rpull]::
+       Pulls from a remote repository over ssh connection
+
+Interogators:
+
+link:git-diff-tree-helper.html[git-diff-tree-helper]::
+       Generates patch format output for git-diff-*
+
+link:git-rpush.html[git-rpush]::
+       Helper "server-side" program used by git-rpull
+
+
+
+Terminology
+-----------
+see README for description
+
+Identifier terminology
+----------------------
+<object>::
+       Indicates any object sha1 identifier
+
+<blob>::
+       Indicates a blob object sha1 identifier
+
+<tree>::
+       Indicates a tree object sha1 identifier
+
+<commit>::
+       Indicates a commit object sha1 identifier
+
+<tree-ish>::
+       Indicates a tree, commit or tag object sha1 identifier.
+       A command that takes a <tree-ish> argument ultimately
+       wants to operate on a <tree> object but automatically
+       dereferences <commit> and <tag> that points at a
+       <tree>.
+
+<type>::
+       Indicates that an object type is required.
+       Currently one of: blob/tree/commit/tag
+
+<file>::
+       Indicates a filename - always relative to the root of
+       the tree structure GIT_INDEX_FILE describes.
+
+Symbolic Identifiers
+--------------------
+Any git comand accepting any <object> can also use the following symbolic notation:
+
+HEAD::
+       indicates the head of the repository (ie the contents of `$GIT_DIR/HEAD`)
+<tag>::
+       a valid tag 'name'+
+       (ie the contents of `$GIT_DIR/refs/tags/<tag>`)
+<head>::
+       a valid head 'name'+
+       (ie the contents of `$GIT_DIR/refs/heads/<head>`)
+<snap>::
+       a valid snapshot 'name'+
+       (ie the contents of `$GIT_DIR/refs/snap/<snap>`)
+
+
+File/Directory Structure
+------------------------
+The git-core manipulates the following areas in the directory:
+
+ .git/        The base (overridden with $GIT_DIR)
+   objects/    The object base (overridden with $GIT_OBJECT_DIRECTORY)
+     ??/       'First 2 chars of object' directories
+
+It can interrogate (but never updates) the following areas:
+
+   refs/       Directories containing symbolic names for objects
+              (each file contains the hex SHA1 + newline)
+     heads/    Commits which are heads of various sorts
+     tags/     Tags, by the tag name (or some local renaming of it)
+     snap/     ????
+   ...         Everything else isn't shared
+   HEAD        Symlink to refs/heads/<something>
+
+Higher level SCMs may provide and manage additional information in the
+GIT_DIR.
+
+Terminology
+-----------
+Each line contains terms used interchangeably
+
+ object database, .git directory
+ directory cache, index
+ id, sha1, sha1-id, sha1 hash
+ type, tag
+ blob, blob object
+ tree, tree object
+ commit, commit object
+ parent
+ root object
+ changeset
+
+
+Environment Variables
+---------------------
+Various git commands use the following environment variables:
+
+The git Repository
+~~~~~~~~~~~~~~~~~~
+These environment variables apply to 'all' core git commands. Nb: it
+is worth noting that they may be used/overridden by SCMS sitting above
+git so take care if using Cogito etc
+
+'GIT_INDEX_FILE'::
+       This environment allows the specification of an alternate
+       cache/index file. If not specified, the default of
+       `$GIT_DIR/index` is used.
+
+'GIT_OBJECT_DIRECTORY'::
+       If the object storage directory is specified via this
+       environment variable then the sha1 directories are created
+       underneath - otherwise the default `$GIT_DIR/objects`
+       directory is used.
+
+'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
+       can be used to search for git objects. New objects will not be
+       written to these directories.
+
+'GIT_DIR'::
+       If the 'GIT_DIR' environment variable is set then it specifies
+       a path to use instead of `./.git` for the base of the
+       repository.
+
+git Commits
+~~~~~~~~~~~
+'GIT_AUTHOR_NAME'::
+'GIT_AUTHOR_EMAIL'::
+'GIT_AUTHOR_DATE'::
+'GIT_COMMITTER_NAME'::
+'GIT_COMMITTER_EMAIL'::
+       see link:git-commit-tree.html[git-commit-tree]
+
+git Diffs
+~~~~~~~~~
+GIT_DIFF_OPTS::
+GIT_EXTERNAL_DIFF::
+       see the "generating patches" section in :
+       link:git-diff-cache.html[git-diff-cache];
+       link:git-diff-files.html[git-diff-files];
+       link:git-diff-tree.html[git-diff-tree]
+
+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
+
index a8d4175..6afcb3e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,10 +7,16 @@
 # BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
 # break unless your underlying filesystem supports those sub-second times
 # (my ext3 doesn't).
-CFLAGS=-g -O2 -Wall
+COPTS=-O2
+CFLAGS=-g $(COPTS) -Wall
+
+prefix=$(HOME)
+bin=$(prefix)/bin
+# dest=
 
 CC=gcc
 AR=ar
+INSTALL=install
 
 SCRIPTS=git-apply-patch-script git-merge-one-file-script git-prune-script \
        git-pull-script git-tag-script git-resolve-script
@@ -21,12 +27,13 @@ PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
        git-check-files git-ls-tree git-merge-base git-merge-cache \
        git-unpack-file git-export git-diff-cache git-convert-cache \
        git-http-pull git-rpush git-rpull git-rev-list git-mktag \
-       git-diff-tree-helper git-tar-tree git-local-pull git-write-blob
+       git-diff-tree-helper git-tar-tree git-local-pull git-write-blob \
+       git-get-tar-commit-id
 
 all: $(PROG)
 
 install: $(PROG) $(SCRIPTS)
-       install $(PROG) $(SCRIPTS) $(HOME)/bin/
+       $(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(bin)
 
 LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
         tag.o date.o
@@ -39,6 +46,8 @@ LIB_OBJS += strbuf.o
 LIB_H += diff.h
 LIB_OBJS += diff.o
 
+LIB_OBJS += gitenv.o
+
 LIBS = $(LIB_FILE)
 LIBS += -lz
 
@@ -51,7 +60,7 @@ ifdef PPC_SHA1
   LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
 else
   SHA1_HEADER=<openssl/sha.h>
-  LIBS += -lssl
+  LIBS += -lcrypto
 endif
 endif
 
@@ -109,6 +118,7 @@ sha1_file.o: $(LIB_H)
 usage.o: $(LIB_H)
 diff.o: $(LIB_H)
 strbuf.o: $(LIB_H)
+gitenv.o: $(LIB_H)
 
 clean:
        rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(LIB_FILE)
diff --git a/README b/README
index d4fa56f..0cccfe8 100644 (file)
--- a/README
+++ b/README
@@ -24,7 +24,7 @@ There are two object abstractions: the "object database", and the
 
 
 
-       The Object Database (SHA1_FILE_DIRECTORY)
+       The Object Database (GIT_OBJECT_DIRECTORY)
 
 
 The object database is literally just a content-addressable collection
diff --git a/cache.h b/cache.h
index f8329ae..ff229ee 100644 (file)
--- a/cache.h
+++ b/cache.h
 #endif
 
 /*
+ * Environment variables transition.
+ * We accept older names for now but warn.
+ */
+extern char *gitenv_bc(const char *);
+#define gitenv(e) (getenv(e) ? : gitenv_bc(e))
+
+/*
  * Basic data structures for the directory cache
  *
  * NOTE NOTE NOTE! This is all in the native CPU byte format. It's
@@ -99,15 +106,15 @@ static inline unsigned int create_ce_mode(unsigned int mode)
 extern struct cache_entry **active_cache;
 extern unsigned int active_nr, active_alloc, active_cache_changed;
 
-#define DB_ENVIRONMENT "SHA1_FILE_DIRECTORY"
-#define DEFAULT_DB_ENVIRONMENT ".git/objects"
-
-#define get_object_directory() (getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT)
-
+#define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
+#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
-#define DEFAULT_INDEX_ENVIRONMENT ".git/index"
 
-#define get_index_file() (getenv(INDEX_ENVIRONMENT) ? : DEFAULT_INDEX_ENVIRONMENT)
+extern char *get_object_directory(void);
+extern char *get_index_file(void);
+
+#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
 
 #define alloc_nr(x) (((x)+16)*3/2)
 
@@ -115,7 +122,9 @@ extern unsigned int active_nr, active_alloc, active_cache_changed;
 extern int read_cache(void);
 extern int write_cache(int newfd, struct cache_entry **cache, int entries);
 extern int cache_name_pos(const char *name, int namelen);
-extern int add_cache_entry(struct cache_entry *ce, int ok_to_add);
+#define ADD_CACHE_OK_TO_ADD 1          /* Ok to add */
+#define ADD_CACHE_OK_TO_REPLACE 2      /* Ok to replace file/directory */
+extern int add_cache_entry(struct cache_entry *ce, int option);
 extern int remove_entry_at(int pos);
 extern int remove_file_from_cache(char *path);
 extern int same_name(struct cache_entry *a, struct cache_entry *b);
index 244ebd1..64ce921 100644 (file)
@@ -48,6 +48,7 @@ static void create_directories(const char *path)
                buf[len] = 0;
                mkdir(buf, 0755);
        }
+       free(buf);
 }
 
 static int create_file(const char *path, unsigned int mode)
index cfd6730..b8dd36f 100644 (file)
@@ -146,11 +146,11 @@ int main(int argc, char **argv)
        datestamp(realdate, sizeof(realdate));
        strcpy(date, realdate);
 
-       commitgecos = getenv("COMMIT_AUTHOR_NAME") ? : realgecos;
-       commitemail = getenv("COMMIT_AUTHOR_EMAIL") ? : realemail;
-       gecos = getenv("AUTHOR_NAME") ? : realgecos;
-       email = getenv("AUTHOR_EMAIL") ? : realemail;
-       audate = getenv("AUTHOR_DATE");
+       commitgecos = gitenv("GIT_COMMITTER_NAME") ? : realgecos;
+       commitemail = gitenv("GIT_COMMITTER_EMAIL") ? : realemail;
+       gecos = gitenv("GIT_AUTHOR_NAME") ? : realgecos;
+       email = gitenv("GIT_AUTHOR_EMAIL") ? : realemail;
+       audate = gitenv("GIT_AUTHOR_DATE");
        if (audate)
                parse_date(audate, date, sizeof(date));
 
index 7e87d28..8452719 100644 (file)
@@ -165,7 +165,7 @@ static void mark_merge_entries(void)
 }
 
 static char *diff_cache_usage =
-"diff-cache [-r] [-z] [-p] [-i] [--cached] <tree sha1>";
+"git-diff-cache [-p] [-r] [-z] [-m] [--cached] <tree sha1>";
 
 int main(int argc, char **argv)
 {
index a683283..51bb658 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2005 Junio C Hamano
  */
+#include <limits.h>
 #include "cache.h"
 #include "strbuf.h"
 #include "diff.h"
diff --git a/diff.c b/diff.c
index 95488cd..3230997 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -4,14 +4,15 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <signal.h>
+#include <limits.h>
 #include "cache.h"
 #include "diff.h"
 
-static char *diff_opts = "-pu";
+static const char *diff_opts = "-pu";
 
 static const char *external_diff(void)
 {
-       static char *external_diff_cmd = NULL;
+       static const char *external_diff_cmd = NULL;
        static int done_preparing = 0;
 
        if (done_preparing)
@@ -25,11 +26,11 @@ static const char *external_diff(void)
         *
         * GIT_DIFF_OPTS="-c";
         */
-       if (getenv("GIT_EXTERNAL_DIFF"))
-               external_diff_cmd = getenv("GIT_EXTERNAL_DIFF");
+       if (gitenv("GIT_EXTERNAL_DIFF"))
+               external_diff_cmd = gitenv("GIT_EXTERNAL_DIFF");
 
        /* In case external diff fails... */
-       diff_opts = getenv("GIT_DIFF_OPTS") ? : diff_opts;
+       diff_opts = gitenv("GIT_DIFF_OPTS") ? : diff_opts;
 
        done_preparing = 1;
        return external_diff_cmd;
index abdec92..a00702b 100644 (file)
@@ -62,6 +62,9 @@ static void check_connectivity(void)
  * So a directory called "a" is ordered _after_ a file
  * called "a.c", because "a/" sorts after "a.c".
  */
+#define TREE_UNORDERED (-1)
+#define TREE_HAS_DUPS  (-2)
+
 static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
 {
        int len1 = strlen(a->name);
@@ -74,7 +77,7 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
        if (cmp < 0)
                return 0;
        if (cmp > 0)
-               return -1;
+               return TREE_UNORDERED;
 
        /*
         * Ok, the first <len> characters are the same.
@@ -83,11 +86,18 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
         */
        c1 = a->name[len];
        c2 = b->name[len];
+       if (!c1 && !c2)
+               /*
+                * git-write-tree used to write out a nonsense tree that has
+                * entries with the same name, one blob and one tree.  Make
+                * sure we do not have duplicate entries.
+                */
+               return TREE_HAS_DUPS;
        if (!c1 && a->directory)
                c1 = '/';
        if (!c2 && b->directory)
                c2 = '/';
-       return c1 < c2 ? 0 : -1;
+       return c1 < c2 ? 0 : TREE_UNORDERED;
 }
 
 static int fsck_tree(struct tree *item)
@@ -123,10 +133,18 @@ static int fsck_tree(struct tree *item)
                }
 
                if (last) {
-                       if (verify_ordered(last, entry) < 0) {
+                       switch (verify_ordered(last, entry)) {
+                       case TREE_UNORDERED:
                                fprintf(stderr, "tree %s not ordered\n",
                                        sha1_to_hex(item->object.sha1));
                                return -1;
+                       case TREE_HAS_DUPS:
+                               fprintf(stderr, "tree %s has duplicate entries for '%s'\n",
+                                       sha1_to_hex(item->object.sha1),
+                                       entry->name);
+                               return -1;
+                       default:
+                               break;
                        }
                }
 
@@ -306,7 +324,7 @@ int main(int argc, char **argv)
                        usage("fsck-cache [--tags] [[--unreachable] [--cache] <head-sha1>*]");
        }
 
-       sha1_dir = getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT;
+       sha1_dir = get_object_directory();
        for (i = 0; i < 256; i++) {
                static char dir[4096];
                sprintf(dir, "%s/%02x", sha1_dir, i);
index 13ec1c4..0849a3e 100755 (executable)
@@ -8,7 +8,7 @@
 #
 
 case "$#" in
-2)
+1)
     echo >&2 "cannot handle unmerged diff on path $1."
     exit 1 ;;
 esac
index 3fb43cc..3e128c6 100755 (executable)
@@ -52,9 +52,9 @@ case "${1:-.}${2:-.}${3:-.}" in
 #
 "$1$2$3")
        echo "Auto-merging $4."
-       orig=$(git-unpack-file $1)
-       src1=$(git-unpack-file $2)
-       src2=$(git-unpack-file $3)
+       orig=`git-unpack-file $1`
+       src1=`git-unpack-file $2`
+       src2=`git-unpack-file $3`
        merge "$src2" "$orig" "$src1"
        ret=$?
        if [ "$6" != "$7" ]; then
@@ -64,7 +64,7 @@ case "${1:-.}${2:-.}${3:-.}" in
                echo "ERROR: Leaving conflict merge in $src2."
                exit 1
        fi
-       sha1=$(git-write-blob "$src2") || {
+       sha1=`git-write-blob "$src2"` || {
                echo "ERROR: Leaving conflict merge in $src2."
        }
        exec git-update-cache --add --cacheinfo "$6" $sha1 "$4" ;;
index 9ba89a5..1a97ccc 100755 (executable)
@@ -11,6 +11,9 @@ do
     shift;
 done
 
+: ${GIT_DIR=.git}
+: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
+
 # Defaulting to include .git/refs/*/* may be debatable from the
 # purist POV but power users can always give explicit parameters
 # to the script anyway.
@@ -19,7 +22,8 @@ case "$#" in
 0)
     x_40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
     x_40="$x_40$x_40$x_40$x_40$x_40$x_40$x_40$x_40"
-    set x $(sed -ne "/^$x_40\$/p" .git/HEAD .git/refs/*/* 2>/dev/null)
+    set x $(sed -ne "/^$x_40\$/p" \
+       "$GIT_DIR"/HEAD "$GIT_DIR"/refs/*/* /dev/null 2>/dev/null)
     shift ;;
 esac
 
@@ -28,9 +32,7 @@ sed -ne '/unreachable /{
     s/unreachable [^ ][^ ]* //
     s|\(..\)|\1/|p
 }' | {
-       case "$SHA1_FILE_DIRECTORY" in
-       '') cd .git/objects/ ;;
-       *) cd "$SHA1_FILE_DIRECTORY" ;;
-       esac || exit
+       cd "$GIT_OBJECT_DIRECTORY" || exit
        xargs -r $dryrun rm -f
 }
+
index 78d2f3d..bd892c7 100755 (executable)
@@ -3,6 +3,9 @@
 merge_repo=$1
 merge_name=${2:-HEAD}
 
+: ${GIT_DIR=.git}
+: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
+
 download_one () {
        # remote_path="$1" local_file="$2"
        case "$1" in
@@ -25,16 +28,19 @@ download_objects () {
                git-local-pull -l -a "$2" "$1/"
                ;;
        *)
-               rsync -avz --ignore-existing "$1/objects/." \
-                       ${SHA_FILE_DIRECTORY:-.git/objects}/.
+               rsync -avz --ignore-existing \
+                       "$1/objects/." "$GIT_OBJECT_DIRECTORY"/.
                ;;
        esac
 }
 
 echo "Getting remote $merge_name"
-download_one "$merge_repo/$merge_name" .git/MERGE_HEAD
+download_one "$merge_repo/$merge_name" "$GIT_DIR"/MERGE_HEAD
 
 echo "Getting object database"
-download_objects "$merge_repo" "$(cat .git/MERGE_HEAD)"
+download_objects "$merge_repo" "$(cat "$GIT_DIR"/MERGE_HEAD)"
 
-git-resolve-script "$(cat .git/HEAD)" "$(cat .git/MERGE_HEAD)" "$merge_repo"
+git-resolve-script \
+       "$(cat "$GIT_DIR"/HEAD)" \
+       "$(cat "$GIT_DIR"/MERGE_HEAD)" \
+       "$merge_repo"
index c2f7a6e..ec646fb 100644 (file)
@@ -1,14 +1,19 @@
 #!/bin/sh
 #
+# Copyright (c) 2005 Linus Torvalds
+#
 # Resolve two trees.
 #
 head="$1"
 merge="$2"
 merge_repo="$3"
 
-rm -f .git/MERGE_HEAD .git/ORIG_HEAD
-echo $head > .git/ORIG_HEAD
-echo $merge > .git/MERGE_HEAD
+: ${GIT_DIR=.git}
+: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
+
+rm -f "$GIT_DIR"/MERGE_HEAD "$GIT_DIR"/ORIG_HEAD
+echo $head > "$GIT_DIR"/ORIG_HEAD
+echo $merge > "$GIT_DIR"/MERGE_HEAD
 
 #
 # The remote name is just used for the message,
@@ -35,7 +40,7 @@ if [ "$common" == "$head" ]; then
        echo "Kill me within 3 seconds.."
        sleep 3
        git-read-tree -m $merge && git-checkout-cache -f -a && git-update-cache --refresh
-       echo $merge > .git/HEAD
+       echo $merge > "$GIT_DIR"/HEAD
        git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
        exit 0
 fi
@@ -51,6 +56,6 @@ if [ $? -ne 0 ]; then
 fi
 result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
 echo "Committed merge $result_commit"
-echo $result_commit > .git/HEAD
+echo $result_commit > "$GIT_DIR"/HEAD
 git-checkout-cache -f -a && git-update-cache --refresh
 git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
index ccc75dc..281d192 100755 (executable)
@@ -1,5 +1,9 @@
 #!/bin/sh
-object=${2:-$(cat .git/HEAD)}
+# Copyright (c) 2005 Linus Torvalds
+
+: ${GIT_DIR=.git}
+
+object=${2:-$(cat "$GIT_DIR"/HEAD)}
 type=$(git-cat-file -t $object) || exit 1
 ( echo -e "object $object\ntype $type\ntag $1\n"; cat ) > .tmp-tag
 rm -f .tmp-tag.asc
diff --git a/gitenv.c b/gitenv.c
new file mode 100644 (file)
index 0000000..ab9396f
--- /dev/null
+++ b/gitenv.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2005 Junio C Hamano
+ */
+#include "cache.h"
+
+/*
+ * This array must be sorted by its canonical name, because
+ * we do look-up by binary search.
+ */
+static struct backward_compatible_env {
+       const char *canonical;
+       const char *old;
+} bc_name[] = {
+       { "GIT_ALTERNATE_OBJECT_DIRECTORIES", "SHA1_FILE_DIRECTORIES" },
+       { "GIT_AUTHOR_DATE", "AUTHOR_DATE" },
+       { "GIT_AUTHOR_EMAIL", "AUTHOR_EMAIL" },
+       { "GIT_AUTHOR_NAME", "AUTHOR_NAME" }, 
+       { "GIT_COMMITTER_EMAIL", "COMMIT_AUTHOR_EMAIL" },
+       { "GIT_COMMITTER_NAME", "COMMIT_AUTHOR_NAME" },
+       { "GIT_OBJECT_DIRECTORY", "SHA1_FILE_DIRECTORY" },
+};
+
+static void warn_old_environment(int pos)
+{
+       int i;
+       static int warned = 0;
+       if (warned)
+               return;
+
+       warned = 1;
+       fprintf(stderr,
+               "warning: Attempting to use %s\n",
+               bc_name[pos].old);
+       fprintf(stderr,
+               "warning: GIT environment variables have been renamed.\n"
+               "warning: Please adjust your scripts and environment.\n");
+       for (i = 0; i < sizeof(bc_name) / sizeof(bc_name[0]); i++) {
+               /* warning is needed only when old name is there and
+                * new name is not.
+                */
+               if (!getenv(bc_name[i].canonical) && getenv(bc_name[i].old))
+                       fprintf(stderr, "warning: old %s => new %s\n",
+                               bc_name[i].old, bc_name[i].canonical);
+       }
+}
+
+char *gitenv_bc(const char *e)
+{
+       int first, last;
+       char *val = getenv(e);
+       if (val)
+               die("gitenv_bc called on existing %s; fix the caller.", e);
+
+       first = 0;
+       last = sizeof(bc_name) / sizeof(bc_name[0]);
+       while (last > first) {
+               int next = (last + first) >> 1;
+               int cmp = strcmp(e, bc_name[next].canonical);
+               if (!cmp) {
+                       val = getenv(bc_name[next].old);
+                       /* If the user has only old name, warn.
+                        * otherwise stay silent.
+                        */
+                       if (val)
+                               warn_old_environment(next);
+                       return val;
+               }
+               if (cmp < 0) {
+                       last = next;
+                       continue;
+               }
+               first = next+1;
+       }
+       return NULL;
+}
index 83f95e8..b6bb783 100644 (file)
--- a/init-db.c
+++ b/init-db.c
@@ -5,7 +5,7 @@
  */
 #include "cache.h"
 
-void safe_create_dir(char *dir)
+void safe_create_dir(const char *dir)
 {
        if (mkdir(dir, 0755) < 0) {
                if (errno != EEXIST) {
@@ -23,14 +23,16 @@ void safe_create_dir(char *dir)
  */
 int main(int argc, char **argv)
 {
-       char *sha1_dir, *path;
+       const char *sha1_dir;
+       char *path;
        int len, i;
 
-       safe_create_dir(".git");
-
-       sha1_dir = getenv(DB_ENVIRONMENT);
-       if (!sha1_dir) {
-               sha1_dir = DEFAULT_DB_ENVIRONMENT;
+       sha1_dir = get_object_directory();
+       if (!gitenv(DB_ENVIRONMENT) && !gitenv(GIT_DIR_ENVIRONMENT)) {
+               /* We create leading paths only when we fall back
+                * to local .git/objects, at least for now.
+                */
+               safe_create_dir(DEFAULT_GIT_DIR_ENVIRONMENT);
                fprintf(stderr, "defaulting to local storage area\n");
        }
        len = strlen(sha1_dir);
index 1eec892..3a342ab 100644 (file)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
+#include <limits.h>
 #include "cache.h"
 #include "commit.h"
 #include <errno.h>
@@ -70,8 +71,7 @@ int fetch(unsigned char *sha1)
                munmap(map, st.st_size);
                close(ofd);
                if (status)
-                       fprintf(stderr, "cannot write %s (%ld bytes)\n",
-                               dest_filename, st.st_size);
+                       fprintf(stderr, "cannot write %s\n", dest_filename);
                else
                        pull_say("copy %s\n", hex);
                return status;
index a6fbf08..da2adf4 100644 (file)
@@ -123,10 +123,112 @@ int same_name(struct cache_entry *a, struct cache_entry *b)
        return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
 }
 
-int add_cache_entry(struct cache_entry *ce, int ok_to_add)
+/* We may be in a situation where we already have path/file and path
+ * is being added, or we already have path and path/file is being
+ * added.  Either one would result in a nonsense tree that has path
+ * twice when git-write-tree tries to write it out.  Prevent it.
+ * 
+ * If ok-to-replace is specified, we remove the conflicting entries
+ * from the cache so the caller should recompute the insert position.
+ * When this happens, we return non-zero.
+ */
+static int check_file_directory_conflict(const struct cache_entry *ce,
+                                        int ok_to_replace)
 {
-       int pos;
+       int pos, replaced = 0;
+       const char *path = ce->name;
+       int namelen = strlen(path);
+       int stage = ce_stage(ce);
+       char *pathbuf = xmalloc(namelen + 1);
+       char *cp;
+
+       memcpy(pathbuf, path, namelen + 1);
+
+       /*
+        * We are inserting path/file.  Do they have path registered at
+        * the same stage?  We need to do this for all the levels of our
+        * subpath.
+        */
+       cp = pathbuf;
+       while (1) {
+               char *ep = strchr(cp, '/');
+               if (!ep)
+                       break;
+               *ep = 0;    /* first cut it at slash */
+               pos = cache_name_pos(pathbuf,
+                                    htons(create_ce_flags(ep-cp, stage)));
+               if (0 <= pos) {
+                       /* Our leading path component is registered as a file,
+                        * and we are trying to make it a directory.  This is
+                        * bad.
+                        */
+                       if (!ok_to_replace) {
+                               free(pathbuf);
+                               return -1;
+                       }
+                       fprintf(stderr, "removing file '%s' to replace it with a directory to create '%s'.\n", pathbuf, path);
+                       remove_entry_at(pos);
+                       replaced = 1;
+               }
+               *ep = '/';  /* then restore it and go downwards */
+               cp = ep + 1;
+       }
+       free(pathbuf);
+
+       /* Do we have an entry in the cache that makes our path a prefix
+        * of it?  That is, are we creating a file where they already expect
+        * a directory there?
+        */
+       pos = cache_name_pos(path,
+                            htons(create_ce_flags(namelen, stage)));
+
+       /* (0 <= pos) cannot happen because add_cache_entry()
+        * should have taken care of that case.
+        */
+       pos = -pos-1;
 
+       /* pos would point at an existing entry that would come immediately
+        * after our path.  It could be the same as our path in higher stage,
+        * or different path but in a lower stage.
+        *
+        * E.g. when we are inserting path at stage 2,
+        *
+        *        1 path
+        * pos->  3 path
+        *        2 path/file1
+        *        3 path/file1
+        *        2 path/file2
+        *        2 patho
+        *
+        * We need to examine pos, ignore it because it is at different
+        * stage, examine next to find the path/file at stage 2, and
+        * complain.  We need to do this until we are not the leading
+        * path of an existing entry anymore.
+        */
+
+       while (pos < active_nr) {
+               struct cache_entry *other = active_cache[pos];
+               if (strncmp(other->name, path, namelen))
+                       break; /* it is not our "subdirectory" anymore */
+               if ((ce_stage(other) == stage) &&
+                   other->name[namelen] == '/') {
+                       if (!ok_to_replace)
+                               return -1;
+                       fprintf(stderr, "removing file '%s' under '%s' to be replaced with a file\n", other->name, path);
+                       remove_entry_at(pos);
+                       replaced = 1;
+                       continue; /* cycle without updating pos */
+               }
+               pos++;
+       }
+       return replaced;
+}
+
+int add_cache_entry(struct cache_entry *ce, int option)
+{
+       int pos;
+       int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
+       int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
        pos = cache_name_pos(ce->name, htons(ce->ce_flags));
 
        /* existing match? Just replace it */
@@ -152,6 +254,13 @@ int add_cache_entry(struct cache_entry *ce, int ok_to_add)
        if (!ok_to_add)
                return -1;
 
+       if (check_file_directory_conflict(ce, ok_to_replace)) {
+               if (!ok_to_replace)
+                       return -1;
+               pos = cache_name_pos(ce->name, htons(ce->ce_flags));
+               pos = -pos-1;
+       }
+
        /* Make sure the array is big enough .. */
        if (active_nr == active_alloc) {
                active_alloc = alloc_nr(active_alloc);
diff --git a/rsh.c b/rsh.c
index 2a52e59..5d1cb9d 100644 (file)
--- a/rsh.c
+++ b/rsh.c
@@ -36,8 +36,8 @@ int setup_connection(int *fd_in, int *fd_out, char *remote_prog,
        *(path++) = '\0';
        /* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */
        snprintf(command, COMMAND_SIZE, 
-                "cd /%s; SHA1_FILE_DIRECTORY=objects %s",
-                path, remote_prog);
+                "cd /%s; %s=objects %s",
+                path, DB_ENVIRONMENT, remote_prog);
        posn = command + strlen(command);
        for (i = 0; i < rmt_argc; i++) {
                *(posn++) = ' ';
index e21f4b3..942b673 100644 (file)
@@ -7,6 +7,7 @@
  * creation etc.
  */
 #include <stdarg.h>
+#include <limits.h>
 #include "cache.h"
 
 #ifndef O_NOATIME
@@ -58,6 +59,38 @@ int get_sha1_file(const char *path, unsigned char *result)
        return get_sha1_hex(buffer, result);
 }
 
+static char *git_dir, *git_object_dir, *git_index_file;
+static void setup_git_env(void)
+{
+       git_dir = gitenv(GIT_DIR_ENVIRONMENT);
+       if (!git_dir)
+               git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
+       git_object_dir = gitenv(DB_ENVIRONMENT);
+       if (!git_object_dir) {
+               git_object_dir = xmalloc(strlen(git_dir) + 9);
+               sprintf(git_object_dir, "%s/objects", git_dir);
+       }
+       git_index_file = gitenv(INDEX_ENVIRONMENT);
+       if (!git_index_file) {
+               git_index_file = xmalloc(strlen(git_dir) + 7);
+               sprintf(git_index_file, "%s/index", git_dir);
+       }
+}
+
+char *get_object_directory(void)
+{
+       if (!git_object_dir)
+               setup_git_env();
+       return git_object_dir;
+}
+
+char *get_index_file(void)
+{
+       if (!git_index_file)
+               setup_git_env();
+       return git_index_file;
+}
+
 int get_sha1(const char *str, unsigned char *sha1)
 {
        static char pathname[PATH_MAX];
@@ -69,15 +102,16 @@ int get_sha1(const char *str, unsigned char *sha1)
                "refs/snap",
                NULL
        };
-       const char *gitdir;
        const char **p;
 
        if (!get_sha1_hex(str, sha1))
                return 0;
 
-       gitdir = ".git";
+       if (!git_dir)
+               setup_git_env();
        for (p = prefix; *p; p++) {
-               snprintf(pathname, sizeof(pathname), "%s/%s/%s", gitdir, *p, str);
+               snprintf(pathname, sizeof(pathname), "%s/%s/%s",
+                        git_dir, *p, str);
                if (!get_sha1_file(pathname, sha1))
                        return 0;
        }
@@ -100,18 +134,34 @@ char * sha1_to_hex(const unsigned char *sha1)
        return buffer;
 }
 
+static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
+{
+       int i;
+       for (i = 0; i < 20; i++) {
+               static char hex[] = "0123456789abcdef";
+               unsigned int val = sha1[i];
+               char *pos = pathbuf + i*2 + (i > 0);
+               *pos++ = hex[val >> 4];
+               *pos = hex[val & 0xf];
+       }
+}
+
 /*
  * NOTE! This returns a statically allocated buffer, so you have to be
  * careful about using it. Do a "strdup()" if you need to save the
  * filename.
+ *
+ * Also note that this returns the location for creating.  Reading
+ * SHA1 file can happen from any alternate directory listed in the
+ * DB_ENVIRONMENT environment variable if it is not found in
+ * the primary object database.
  */
 char *sha1_file_name(const unsigned char *sha1)
 {
-       int i;
        static char *name, *base;
 
        if (!base) {
-               char *sha1_file_directory = getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT;
+               const char *sha1_file_directory = get_object_directory();
                int len = strlen(sha1_file_directory);
                base = xmalloc(len + 60);
                memcpy(base, sha1_file_directory, len);
@@ -120,16 +170,94 @@ char *sha1_file_name(const unsigned char *sha1)
                base[len+3] = '/';
                name = base + len + 1;
        }
-       for (i = 0; i < 20; i++) {
-               static char hex[] = "0123456789abcdef";
-               unsigned int val = sha1[i];
-               char *pos = name + i*2 + (i > 0);
-               *pos++ = hex[val >> 4];
-               *pos = hex[val & 0xf];
-       }
+       fill_sha1_path(name, sha1);
        return base;
 }
 
+static struct alternate_object_database {
+       char *base;
+       char *name;
+} *alt_odb;
+
+/*
+ * 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.
+ */
+static void prepare_alt_odb(void)
+{
+       int pass, totlen, i;
+       const char *cp, *last;
+       char *op = 0;
+       const char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
+
+       /* 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 = 0;
+               op = (char*)(&alt_odb[i+1]);
+       }
+}
+
+static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
+{
+       int i;
+       char *name = sha1_file_name(sha1);
+
+       if (!stat(name, st))
+               return name;
+       if (!alt_odb)
+               prepare_alt_odb();
+       for (i = 0; (name = alt_odb[i].name) != NULL; i++) {
+               fill_sha1_path(name, sha1);
+               if (!stat(alt_odb[i].base, st))
+                       return alt_odb[i].base;
+       }
+       return NULL;
+}
+
 int check_sha1_signature(unsigned char *sha1, void *map, unsigned long size, const char *type)
 {
        char header[100];
@@ -145,10 +273,15 @@ int check_sha1_signature(unsigned char *sha1, void *map, unsigned long size, con
 
 void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
 {
-       char *filename = sha1_file_name(sha1);
        struct stat st;
        void *map;
        int fd;
+       char *filename = find_sha1_file(sha1, &st);
+
+       if (!filename) {
+               error("cannot map sha1 file %s", sha1_to_hex(sha1));
+               return NULL;
+       }
 
        fd = open(filename, O_RDONLY | sha1_file_open_flag);
        if (fd < 0) {
@@ -167,10 +300,6 @@ void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
                /* If it failed once, it will probably fail again. Stop using O_NOATIME */
                sha1_file_open_flag = 0;
        }
-       if (fstat(fd, &st) < 0) {
-               close(fd);
-               return NULL;
-       }
        map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        close(fd);
        if (-1 == (int)(long)map)
@@ -315,6 +444,7 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
        }
 
        snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
+
        fd = mkstemp(tmpfile);
        if (fd < 0) {
                fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno));
@@ -349,6 +479,7 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
                die("unable to write file");
        fchmod(fd, 0444);
        close(fd);
+       free(compressed);
 
        ret = link(tmpfile, filename);
        if (ret < 0) {
@@ -442,12 +573,8 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd)
 
 int has_sha1_file(const unsigned char *sha1)
 {
-       char *filename = sha1_file_name(sha1);
        struct stat st;
-
-       if (!stat(filename, &st))
-               return 1;
-       return 0;
+       return !!find_sha1_file(sha1, &st);
 }
 
 int index_fd(unsigned char *sha1, int fd, struct stat *st)
diff --git a/tree.c b/tree.c
index d9777bf..a978c53 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -18,7 +18,7 @@ static int read_one_entry(unsigned char *sha1, const char *base, int baselen, co
        memcpy(ce->name, base, baselen);
        memcpy(ce->name + baselen, pathname, len+1);
        memcpy(ce->sha1, sha1, 20);
-       return add_cache_entry(ce, 1);
+       return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
 }
 
 static int read_tree_recursive(void *buffer, unsigned long size,
index 735d199..2f5d620 100644 (file)
@@ -13,7 +13,7 @@
  * like "update-cache *" and suddenly having all the object
  * files be revision controlled.
  */
-static int allow_add = 0, allow_remove = 0, not_new = 0;
+static int allow_add = 0, allow_remove = 0, allow_replace = 0, not_new = 0;
 
 /* Three functions to allow overloaded pointer return; see linux/err.h */
 static inline void *ERR_PTR(long error)
@@ -53,14 +53,23 @@ static void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
 
 static int add_file_to_cache(char *path)
 {
-       int size, namelen;
+       int size, namelen, option, status;
        struct cache_entry *ce;
        struct stat st;
        int fd;
        char *target;
 
-       if (lstat(path, &st) < 0) {
-               if (errno == ENOENT || errno == ENOTDIR) {
+       status = lstat(path, &st);
+       if (status < 0 || S_ISDIR(st.st_mode)) {
+               /* When we used to have "path" and now we want to add
+                * "path/file", we need a way to remove "path" before
+                * being able to add "path/file".  However,
+                * "git-update-cache --remove path" would not work.
+                * --force-remove can be used but this is more user
+                * friendly, especially since we can do the opposite
+                * case just fine without --force-remove.
+                */
+               if (status == 0 || (errno == ENOENT || errno == ENOTDIR)) {
                        if (allow_remove)
                                return remove_file_from_cache(path);
                }
@@ -95,7 +104,9 @@ static int add_file_to_cache(char *path)
        default:
                return -1;
        }
-       return add_cache_entry(ce, allow_add);
+       option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
+       option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
+       return add_cache_entry(ce, option);
 }
 
 static int match_data(int fd, void *buffer, unsigned long size)
@@ -273,7 +284,7 @@ inside:
 
 static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
 {
-       int size, len;
+       int size, len, option;
        unsigned int mode;
        unsigned char sha1[20];
        struct cache_entry *ce;
@@ -294,7 +305,9 @@ static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
        memcpy(ce->name, arg3, len);
        ce->ce_flags = htons(len);
        ce->ce_mode = create_ce_mode(mode);
-       return add_cache_entry(ce, allow_add);
+       option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
+       option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
+       return add_cache_entry(ce, option);
 }
 
 static const char *lockfile_name = NULL;
@@ -343,6 +356,10 @@ int main(int argc, char **argv)
                                allow_add = 1;
                                continue;
                        }
+                       if (!strcmp(path, "--replace")) {
+                               allow_replace = 1;
+                               continue;
+                       }
                        if (!strcmp(path, "--remove")) {
                                allow_remove = 1;
                                continue;
@@ -352,8 +369,10 @@ int main(int argc, char **argv)
                                continue;
                        }
                        if (!strcmp(path, "--cacheinfo")) {
-                               if (i+3 >= argc || add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+                               if (i+3 >= argc)
                                        die("update-cache: --cacheinfo <mode> <sha1> <path>");
+                               if (add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+                                       die("update-cache: --cacheinfo cannot add %s", argv[i+3]);
                                i += 3;
                                continue;
                        }
index d801d7f..e3c0a02 100644 (file)
@@ -84,7 +84,7 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b
 
 int main(int argc, char **argv)
 {
-       int i, unmerged;
+       int i, funny;
        int entries = read_cache();
        unsigned char sha1[20];
 
@@ -92,18 +92,45 @@ int main(int argc, char **argv)
                die("write-tree: error reading cache");
 
        /* Verify that the tree is merged */
-       unmerged = 0;
+       funny = 0;
        for (i = 0; i < entries; i++) {
                struct cache_entry *ce = active_cache[i];
                if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
-                       if (++unmerged > 10) {
+                       if (10 < ++funny) {
                                fprintf(stderr, "...\n");
                                break;
                        }
                        fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1));
                }
        }
-       if (unmerged)
+       if (funny)
+               die("write-tree: not able to write tree");
+
+       /* Also verify that the cache does not have path and path/file
+        * at the same time.  At this point we know the cache has only
+        * stage 0 entries.
+        */
+       funny = 0;
+       for (i = 0; i < entries - 1; i++) {
+               /* path/file always comes after path because of the way
+                * the cache is sorted.  Also path can appear only once,
+                * which means conflicting one would immediately follow.
+                */
+               const char *this_name = active_cache[i]->name;
+               const char *next_name = active_cache[i+1]->name;
+               int this_len = strlen(this_name);
+               if (this_len < strlen(next_name) &&
+                   strncmp(this_name, next_name, this_len) == 0 &&
+                   next_name[this_len] == '/') {
+                       if (10 < ++funny) {
+                               fprintf(stderr, "...\n");
+                               break;
+                       }
+                       fprintf(stderr, "You have both %s and %s\n",
+                               this_name, next_name);
+               }
+       }
+       if (funny)
                die("write-tree: not able to write tree");
 
        /* Ok, write it out */