maint
commit
f1a7eb36b0
|
@ -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 $<
|
File diff suppressed because it is too large
Load Diff
|
@ -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>.
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
18
Makefile
18
Makefile
|
@ -7,10 +7,16 @@
|
||||||
# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
|
# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
|
||||||
# break unless your underlying filesystem supports those sub-second times
|
# break unless your underlying filesystem supports those sub-second times
|
||||||
# (my ext3 doesn't).
|
# (my ext3 doesn't).
|
||||||
CFLAGS=-g -O2 -Wall
|
COPTS=-O2
|
||||||
|
CFLAGS=-g $(COPTS) -Wall
|
||||||
|
|
||||||
|
prefix=$(HOME)
|
||||||
|
bin=$(prefix)/bin
|
||||||
|
# dest=
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
AR=ar
|
AR=ar
|
||||||
|
INSTALL=install
|
||||||
|
|
||||||
SCRIPTS=git-apply-patch-script git-merge-one-file-script git-prune-script \
|
SCRIPTS=git-apply-patch-script git-merge-one-file-script git-prune-script \
|
||||||
git-pull-script git-tag-script git-resolve-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-check-files git-ls-tree git-merge-base git-merge-cache \
|
||||||
git-unpack-file git-export git-diff-cache git-convert-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-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)
|
all: $(PROG)
|
||||||
|
|
||||||
install: $(PROG) $(SCRIPTS)
|
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 \
|
LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
|
||||||
tag.o date.o
|
tag.o date.o
|
||||||
|
@ -39,6 +46,8 @@ LIB_OBJS += strbuf.o
|
||||||
LIB_H += diff.h
|
LIB_H += diff.h
|
||||||
LIB_OBJS += diff.o
|
LIB_OBJS += diff.o
|
||||||
|
|
||||||
|
LIB_OBJS += gitenv.o
|
||||||
|
|
||||||
LIBS = $(LIB_FILE)
|
LIBS = $(LIB_FILE)
|
||||||
LIBS += -lz
|
LIBS += -lz
|
||||||
|
|
||||||
|
@ -51,7 +60,7 @@ ifdef PPC_SHA1
|
||||||
LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
|
LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
|
||||||
else
|
else
|
||||||
SHA1_HEADER=<openssl/sha.h>
|
SHA1_HEADER=<openssl/sha.h>
|
||||||
LIBS += -lssl
|
LIBS += -lcrypto
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -109,6 +118,7 @@ sha1_file.o: $(LIB_H)
|
||||||
usage.o: $(LIB_H)
|
usage.o: $(LIB_H)
|
||||||
diff.o: $(LIB_H)
|
diff.o: $(LIB_H)
|
||||||
strbuf.o: $(LIB_H)
|
strbuf.o: $(LIB_H)
|
||||||
|
gitenv.o: $(LIB_H)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(LIB_FILE)
|
rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(LIB_FILE)
|
||||||
|
|
2
README
2
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
|
The object database is literally just a content-addressable collection
|
||||||
|
|
25
cache.h
25
cache.h
|
@ -30,6 +30,13 @@
|
||||||
#define DTYPE(de) DT_UNKNOWN
|
#define DTYPE(de) DT_UNKNOWN
|
||||||
#endif
|
#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
|
* Basic data structures for the directory cache
|
||||||
*
|
*
|
||||||
|
@ -99,15 +106,15 @@ static inline unsigned int create_ce_mode(unsigned int mode)
|
||||||
extern struct cache_entry **active_cache;
|
extern struct cache_entry **active_cache;
|
||||||
extern unsigned int active_nr, active_alloc, active_cache_changed;
|
extern unsigned int active_nr, active_alloc, active_cache_changed;
|
||||||
|
|
||||||
#define DB_ENVIRONMENT "SHA1_FILE_DIRECTORY"
|
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
|
||||||
#define DEFAULT_DB_ENVIRONMENT ".git/objects"
|
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
|
||||||
|
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
|
||||||
#define get_object_directory() (getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT)
|
|
||||||
|
|
||||||
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
|
#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)
|
#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 read_cache(void);
|
||||||
extern int write_cache(int newfd, struct cache_entry **cache, int entries);
|
extern int write_cache(int newfd, struct cache_entry **cache, int entries);
|
||||||
extern int cache_name_pos(const char *name, int namelen);
|
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_entry_at(int pos);
|
||||||
extern int remove_file_from_cache(char *path);
|
extern int remove_file_from_cache(char *path);
|
||||||
extern int same_name(struct cache_entry *a, struct cache_entry *b);
|
extern int same_name(struct cache_entry *a, struct cache_entry *b);
|
||||||
|
|
|
@ -48,6 +48,7 @@ static void create_directories(const char *path)
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
mkdir(buf, 0755);
|
mkdir(buf, 0755);
|
||||||
}
|
}
|
||||||
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_file(const char *path, unsigned int mode)
|
static int create_file(const char *path, unsigned int mode)
|
||||||
|
|
|
@ -146,11 +146,11 @@ int main(int argc, char **argv)
|
||||||
datestamp(realdate, sizeof(realdate));
|
datestamp(realdate, sizeof(realdate));
|
||||||
strcpy(date, realdate);
|
strcpy(date, realdate);
|
||||||
|
|
||||||
commitgecos = getenv("COMMIT_AUTHOR_NAME") ? : realgecos;
|
commitgecos = gitenv("GIT_COMMITTER_NAME") ? : realgecos;
|
||||||
commitemail = getenv("COMMIT_AUTHOR_EMAIL") ? : realemail;
|
commitemail = gitenv("GIT_COMMITTER_EMAIL") ? : realemail;
|
||||||
gecos = getenv("AUTHOR_NAME") ? : realgecos;
|
gecos = gitenv("GIT_AUTHOR_NAME") ? : realgecos;
|
||||||
email = getenv("AUTHOR_EMAIL") ? : realemail;
|
email = gitenv("GIT_AUTHOR_EMAIL") ? : realemail;
|
||||||
audate = getenv("AUTHOR_DATE");
|
audate = gitenv("GIT_AUTHOR_DATE");
|
||||||
if (audate)
|
if (audate)
|
||||||
parse_date(audate, date, sizeof(date));
|
parse_date(audate, date, sizeof(date));
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ static void mark_merge_entries(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *diff_cache_usage =
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005 Junio C Hamano
|
* Copyright (C) 2005 Junio C Hamano
|
||||||
*/
|
*/
|
||||||
|
#include <limits.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
|
|
11
diff.c
11
diff.c
|
@ -4,14 +4,15 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
|
|
||||||
static char *diff_opts = "-pu";
|
static const char *diff_opts = "-pu";
|
||||||
|
|
||||||
static const char *external_diff(void)
|
static const char *external_diff(void)
|
||||||
{
|
{
|
||||||
static char *external_diff_cmd = NULL;
|
static const char *external_diff_cmd = NULL;
|
||||||
static int done_preparing = 0;
|
static int done_preparing = 0;
|
||||||
|
|
||||||
if (done_preparing)
|
if (done_preparing)
|
||||||
|
@ -25,11 +26,11 @@ static const char *external_diff(void)
|
||||||
*
|
*
|
||||||
* GIT_DIFF_OPTS="-c";
|
* GIT_DIFF_OPTS="-c";
|
||||||
*/
|
*/
|
||||||
if (getenv("GIT_EXTERNAL_DIFF"))
|
if (gitenv("GIT_EXTERNAL_DIFF"))
|
||||||
external_diff_cmd = getenv("GIT_EXTERNAL_DIFF");
|
external_diff_cmd = gitenv("GIT_EXTERNAL_DIFF");
|
||||||
|
|
||||||
/* In case external diff fails... */
|
/* In case external diff fails... */
|
||||||
diff_opts = getenv("GIT_DIFF_OPTS") ? : diff_opts;
|
diff_opts = gitenv("GIT_DIFF_OPTS") ? : diff_opts;
|
||||||
|
|
||||||
done_preparing = 1;
|
done_preparing = 1;
|
||||||
return external_diff_cmd;
|
return external_diff_cmd;
|
||||||
|
|
26
fsck-cache.c
26
fsck-cache.c
|
@ -62,6 +62,9 @@ static void check_connectivity(void)
|
||||||
* So a directory called "a" is ordered _after_ a file
|
* So a directory called "a" is ordered _after_ a file
|
||||||
* called "a.c", because "a/" sorts after "a.c".
|
* 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)
|
static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
|
||||||
{
|
{
|
||||||
int len1 = strlen(a->name);
|
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)
|
if (cmp < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
return -1;
|
return TREE_UNORDERED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok, the first <len> characters are the same.
|
* 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];
|
c1 = a->name[len];
|
||||||
c2 = b->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)
|
if (!c1 && a->directory)
|
||||||
c1 = '/';
|
c1 = '/';
|
||||||
if (!c2 && b->directory)
|
if (!c2 && b->directory)
|
||||||
c2 = '/';
|
c2 = '/';
|
||||||
return c1 < c2 ? 0 : -1;
|
return c1 < c2 ? 0 : TREE_UNORDERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fsck_tree(struct tree *item)
|
static int fsck_tree(struct tree *item)
|
||||||
|
@ -123,10 +133,18 @@ static int fsck_tree(struct tree *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
if (verify_ordered(last, entry) < 0) {
|
switch (verify_ordered(last, entry)) {
|
||||||
|
case TREE_UNORDERED:
|
||||||
fprintf(stderr, "tree %s not ordered\n",
|
fprintf(stderr, "tree %s not ordered\n",
|
||||||
sha1_to_hex(item->object.sha1));
|
sha1_to_hex(item->object.sha1));
|
||||||
return -1;
|
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>*]");
|
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++) {
|
for (i = 0; i < 256; i++) {
|
||||||
static char dir[4096];
|
static char dir[4096];
|
||||||
sprintf(dir, "%s/%02x", sha1_dir, i);
|
sprintf(dir, "%s/%02x", sha1_dir, i);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
case "$#" in
|
case "$#" in
|
||||||
2)
|
1)
|
||||||
echo >&2 "cannot handle unmerged diff on path $1."
|
echo >&2 "cannot handle unmerged diff on path $1."
|
||||||
exit 1 ;;
|
exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -52,9 +52,9 @@ case "${1:-.}${2:-.}${3:-.}" in
|
||||||
#
|
#
|
||||||
"$1$2$3")
|
"$1$2$3")
|
||||||
echo "Auto-merging $4."
|
echo "Auto-merging $4."
|
||||||
orig=$(git-unpack-file $1)
|
orig=`git-unpack-file $1`
|
||||||
src1=$(git-unpack-file $2)
|
src1=`git-unpack-file $2`
|
||||||
src2=$(git-unpack-file $3)
|
src2=`git-unpack-file $3`
|
||||||
merge "$src2" "$orig" "$src1"
|
merge "$src2" "$orig" "$src1"
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$6" != "$7" ]; then
|
if [ "$6" != "$7" ]; then
|
||||||
|
@ -64,7 +64,7 @@ case "${1:-.}${2:-.}${3:-.}" in
|
||||||
echo "ERROR: Leaving conflict merge in $src2."
|
echo "ERROR: Leaving conflict merge in $src2."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sha1=$(git-write-blob "$src2") || {
|
sha1=`git-write-blob "$src2"` || {
|
||||||
echo "ERROR: Leaving conflict merge in $src2."
|
echo "ERROR: Leaving conflict merge in $src2."
|
||||||
}
|
}
|
||||||
exec git-update-cache --add --cacheinfo "$6" $sha1 "$4" ;;
|
exec git-update-cache --add --cacheinfo "$6" $sha1 "$4" ;;
|
||||||
|
|
|
@ -11,6 +11,9 @@ do
|
||||||
shift;
|
shift;
|
||||||
done
|
done
|
||||||
|
|
||||||
|
: ${GIT_DIR=.git}
|
||||||
|
: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
|
||||||
|
|
||||||
# Defaulting to include .git/refs/*/* may be debatable from the
|
# Defaulting to include .git/refs/*/* may be debatable from the
|
||||||
# purist POV but power users can always give explicit parameters
|
# purist POV but power users can always give explicit parameters
|
||||||
# to the script anyway.
|
# to the script anyway.
|
||||||
|
@ -19,7 +22,8 @@ case "$#" in
|
||||||
0)
|
0)
|
||||||
x_40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
|
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"
|
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 ;;
|
shift ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -28,9 +32,7 @@ sed -ne '/unreachable /{
|
||||||
s/unreachable [^ ][^ ]* //
|
s/unreachable [^ ][^ ]* //
|
||||||
s|\(..\)|\1/|p
|
s|\(..\)|\1/|p
|
||||||
}' | {
|
}' | {
|
||||||
case "$SHA1_FILE_DIRECTORY" in
|
cd "$GIT_OBJECT_DIRECTORY" || exit
|
||||||
'') cd .git/objects/ ;;
|
|
||||||
*) cd "$SHA1_FILE_DIRECTORY" ;;
|
|
||||||
esac || exit
|
|
||||||
xargs -r $dryrun rm -f
|
xargs -r $dryrun rm -f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
merge_repo=$1
|
merge_repo=$1
|
||||||
merge_name=${2:-HEAD}
|
merge_name=${2:-HEAD}
|
||||||
|
|
||||||
|
: ${GIT_DIR=.git}
|
||||||
|
: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
|
||||||
|
|
||||||
download_one () {
|
download_one () {
|
||||||
# remote_path="$1" local_file="$2"
|
# remote_path="$1" local_file="$2"
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
@ -25,16 +28,19 @@ download_objects () {
|
||||||
git-local-pull -l -a "$2" "$1/"
|
git-local-pull -l -a "$2" "$1/"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
rsync -avz --ignore-existing "$1/objects/." \
|
rsync -avz --ignore-existing \
|
||||||
${SHA_FILE_DIRECTORY:-.git/objects}/.
|
"$1/objects/." "$GIT_OBJECT_DIRECTORY"/.
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Getting remote $merge_name"
|
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"
|
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"
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
|
# Copyright (c) 2005 Linus Torvalds
|
||||||
|
#
|
||||||
# Resolve two trees.
|
# Resolve two trees.
|
||||||
#
|
#
|
||||||
head="$1"
|
head="$1"
|
||||||
merge="$2"
|
merge="$2"
|
||||||
merge_repo="$3"
|
merge_repo="$3"
|
||||||
|
|
||||||
rm -f .git/MERGE_HEAD .git/ORIG_HEAD
|
: ${GIT_DIR=.git}
|
||||||
echo $head > .git/ORIG_HEAD
|
: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
|
||||||
echo $merge > .git/MERGE_HEAD
|
|
||||||
|
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,
|
# The remote name is just used for the message,
|
||||||
|
@ -35,7 +40,7 @@ if [ "$common" == "$head" ]; then
|
||||||
echo "Kill me within 3 seconds.."
|
echo "Kill me within 3 seconds.."
|
||||||
sleep 3
|
sleep 3
|
||||||
git-read-tree -m $merge && git-checkout-cache -f -a && git-update-cache --refresh
|
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
|
git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
@ -51,6 +56,6 @@ if [ $? -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
|
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
|
||||||
echo "Committed merge $result_commit"
|
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-checkout-cache -f -a && git-update-cache --refresh
|
||||||
git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
|
git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
#!/bin/sh
|
#!/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
|
type=$(git-cat-file -t $object) || exit 1
|
||||||
( echo -e "object $object\ntype $type\ntag $1\n"; cat ) > .tmp-tag
|
( echo -e "object $object\ntype $type\ntag $1\n"; cat ) > .tmp-tag
|
||||||
rm -f .tmp-tag.asc
|
rm -f .tmp-tag.asc
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
16
init-db.c
16
init-db.c
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
void safe_create_dir(char *dir)
|
void safe_create_dir(const char *dir)
|
||||||
{
|
{
|
||||||
if (mkdir(dir, 0755) < 0) {
|
if (mkdir(dir, 0755) < 0) {
|
||||||
if (errno != EEXIST) {
|
if (errno != EEXIST) {
|
||||||
|
@ -23,14 +23,16 @@ void safe_create_dir(char *dir)
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *sha1_dir, *path;
|
const char *sha1_dir;
|
||||||
|
char *path;
|
||||||
int len, i;
|
int len, i;
|
||||||
|
|
||||||
safe_create_dir(".git");
|
sha1_dir = get_object_directory();
|
||||||
|
if (!gitenv(DB_ENVIRONMENT) && !gitenv(GIT_DIR_ENVIRONMENT)) {
|
||||||
sha1_dir = getenv(DB_ENVIRONMENT);
|
/* We create leading paths only when we fall back
|
||||||
if (!sha1_dir) {
|
* to local .git/objects, at least for now.
|
||||||
sha1_dir = DEFAULT_DB_ENVIRONMENT;
|
*/
|
||||||
|
safe_create_dir(DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||||
fprintf(stderr, "defaulting to local storage area\n");
|
fprintf(stderr, "defaulting to local storage area\n");
|
||||||
}
|
}
|
||||||
len = strlen(sha1_dir);
|
len = strlen(sha1_dir);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -70,8 +71,7 @@ int fetch(unsigned char *sha1)
|
||||||
munmap(map, st.st_size);
|
munmap(map, st.st_size);
|
||||||
close(ofd);
|
close(ofd);
|
||||||
if (status)
|
if (status)
|
||||||
fprintf(stderr, "cannot write %s (%ld bytes)\n",
|
fprintf(stderr, "cannot write %s\n", dest_filename);
|
||||||
dest_filename, st.st_size);
|
|
||||||
else
|
else
|
||||||
pull_say("copy %s\n", hex);
|
pull_say("copy %s\n", hex);
|
||||||
return status;
|
return status;
|
||||||
|
|
113
read-cache.c
113
read-cache.c
|
@ -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);
|
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, 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 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));
|
pos = cache_name_pos(ce->name, htons(ce->ce_flags));
|
||||||
|
|
||||||
/* existing match? Just replace it */
|
/* 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)
|
if (!ok_to_add)
|
||||||
return -1;
|
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 .. */
|
/* Make sure the array is big enough .. */
|
||||||
if (active_nr == active_alloc) {
|
if (active_nr == active_alloc) {
|
||||||
active_alloc = alloc_nr(active_alloc);
|
active_alloc = alloc_nr(active_alloc);
|
||||||
|
|
4
rsh.c
4
rsh.c
|
@ -36,8 +36,8 @@ int setup_connection(int *fd_in, int *fd_out, char *remote_prog,
|
||||||
*(path++) = '\0';
|
*(path++) = '\0';
|
||||||
/* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */
|
/* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */
|
||||||
snprintf(command, COMMAND_SIZE,
|
snprintf(command, COMMAND_SIZE,
|
||||||
"cd /%s; SHA1_FILE_DIRECTORY=objects %s",
|
"cd /%s; %s=objects %s",
|
||||||
path, remote_prog);
|
path, DB_ENVIRONMENT, remote_prog);
|
||||||
posn = command + strlen(command);
|
posn = command + strlen(command);
|
||||||
for (i = 0; i < rmt_argc; i++) {
|
for (i = 0; i < rmt_argc; i++) {
|
||||||
*(posn++) = ' ';
|
*(posn++) = ' ';
|
||||||
|
|
171
sha1_file.c
171
sha1_file.c
|
@ -7,6 +7,7 @@
|
||||||
* creation etc.
|
* creation etc.
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#ifndef O_NOATIME
|
#ifndef O_NOATIME
|
||||||
|
@ -58,6 +59,38 @@ int get_sha1_file(const char *path, unsigned char *result)
|
||||||
return get_sha1_hex(buffer, 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)
|
int get_sha1(const char *str, unsigned char *sha1)
|
||||||
{
|
{
|
||||||
static char pathname[PATH_MAX];
|
static char pathname[PATH_MAX];
|
||||||
|
@ -69,15 +102,16 @@ int get_sha1(const char *str, unsigned char *sha1)
|
||||||
"refs/snap",
|
"refs/snap",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
const char *gitdir;
|
|
||||||
const char **p;
|
const char **p;
|
||||||
|
|
||||||
if (!get_sha1_hex(str, sha1))
|
if (!get_sha1_hex(str, sha1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
gitdir = ".git";
|
if (!git_dir)
|
||||||
|
setup_git_env();
|
||||||
for (p = prefix; *p; p++) {
|
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))
|
if (!get_sha1_file(pathname, sha1))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -100,18 +134,34 @@ char * sha1_to_hex(const unsigned char *sha1)
|
||||||
return buffer;
|
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
|
* 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
|
* careful about using it. Do a "strdup()" if you need to save the
|
||||||
* filename.
|
* 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)
|
char *sha1_file_name(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
static char *name, *base;
|
static char *name, *base;
|
||||||
|
|
||||||
if (!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);
|
int len = strlen(sha1_file_directory);
|
||||||
base = xmalloc(len + 60);
|
base = xmalloc(len + 60);
|
||||||
memcpy(base, sha1_file_directory, len);
|
memcpy(base, sha1_file_directory, len);
|
||||||
|
@ -120,16 +170,94 @@ char *sha1_file_name(const unsigned char *sha1)
|
||||||
base[len+3] = '/';
|
base[len+3] = '/';
|
||||||
name = base + len + 1;
|
name = base + len + 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 20; i++) {
|
fill_sha1_path(name, sha1);
|
||||||
static char hex[] = "0123456789abcdef";
|
|
||||||
unsigned int val = sha1[i];
|
|
||||||
char *pos = name + i*2 + (i > 0);
|
|
||||||
*pos++ = hex[val >> 4];
|
|
||||||
*pos = hex[val & 0xf];
|
|
||||||
}
|
|
||||||
return base;
|
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)
|
int check_sha1_signature(unsigned char *sha1, void *map, unsigned long size, const char *type)
|
||||||
{
|
{
|
||||||
char header[100];
|
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)
|
void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
|
||||||
{
|
{
|
||||||
char *filename = sha1_file_name(sha1);
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
void *map;
|
void *map;
|
||||||
int fd;
|
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);
|
fd = open(filename, O_RDONLY | sha1_file_open_flag);
|
||||||
if (fd < 0) {
|
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 */
|
/* If it failed once, it will probably fail again. Stop using O_NOATIME */
|
||||||
sha1_file_open_flag = 0;
|
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);
|
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (-1 == (int)(long)map)
|
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());
|
snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
|
||||||
|
|
||||||
fd = mkstemp(tmpfile);
|
fd = mkstemp(tmpfile);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno));
|
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");
|
die("unable to write file");
|
||||||
fchmod(fd, 0444);
|
fchmod(fd, 0444);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
free(compressed);
|
||||||
|
|
||||||
ret = link(tmpfile, filename);
|
ret = link(tmpfile, filename);
|
||||||
if (ret < 0) {
|
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)
|
int has_sha1_file(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
char *filename = sha1_file_name(sha1);
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
return !!find_sha1_file(sha1, &st);
|
||||||
if (!stat(filename, &st))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int index_fd(unsigned char *sha1, int fd, struct stat *st)
|
int index_fd(unsigned char *sha1, int fd, struct stat *st)
|
||||||
|
|
2
tree.c
2
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, base, baselen);
|
||||||
memcpy(ce->name + baselen, pathname, len+1);
|
memcpy(ce->name + baselen, pathname, len+1);
|
||||||
memcpy(ce->sha1, sha1, 20);
|
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,
|
static int read_tree_recursive(void *buffer, unsigned long size,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* like "update-cache *" and suddenly having all the object
|
* like "update-cache *" and suddenly having all the object
|
||||||
* files be revision controlled.
|
* 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 */
|
/* Three functions to allow overloaded pointer return; see linux/err.h */
|
||||||
static inline void *ERR_PTR(long error)
|
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)
|
static int add_file_to_cache(char *path)
|
||||||
{
|
{
|
||||||
int size, namelen;
|
int size, namelen, option, status;
|
||||||
struct cache_entry *ce;
|
struct cache_entry *ce;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
char *target;
|
char *target;
|
||||||
|
|
||||||
if (lstat(path, &st) < 0) {
|
status = lstat(path, &st);
|
||||||
if (errno == ENOENT || errno == ENOTDIR) {
|
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)
|
if (allow_remove)
|
||||||
return remove_file_from_cache(path);
|
return remove_file_from_cache(path);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +104,9 @@ static int add_file_to_cache(char *path)
|
||||||
default:
|
default:
|
||||||
return -1;
|
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)
|
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)
|
static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
|
||||||
{
|
{
|
||||||
int size, len;
|
int size, len, option;
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
struct cache_entry *ce;
|
struct cache_entry *ce;
|
||||||
|
@ -294,7 +305,9 @@ static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
|
||||||
memcpy(ce->name, arg3, len);
|
memcpy(ce->name, arg3, len);
|
||||||
ce->ce_flags = htons(len);
|
ce->ce_flags = htons(len);
|
||||||
ce->ce_mode = create_ce_mode(mode);
|
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;
|
static const char *lockfile_name = NULL;
|
||||||
|
@ -343,6 +356,10 @@ int main(int argc, char **argv)
|
||||||
allow_add = 1;
|
allow_add = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(path, "--replace")) {
|
||||||
|
allow_replace = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp(path, "--remove")) {
|
if (!strcmp(path, "--remove")) {
|
||||||
allow_remove = 1;
|
allow_remove = 1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -352,8 +369,10 @@ int main(int argc, char **argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(path, "--cacheinfo")) {
|
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>");
|
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;
|
i += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
35
write-tree.c
35
write-tree.c
|
@ -84,7 +84,7 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, unmerged;
|
int i, funny;
|
||||||
int entries = read_cache();
|
int entries = read_cache();
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
|
|
||||||
|
@ -92,18 +92,45 @@ int main(int argc, char **argv)
|
||||||
die("write-tree: error reading cache");
|
die("write-tree: error reading cache");
|
||||||
|
|
||||||
/* Verify that the tree is merged */
|
/* Verify that the tree is merged */
|
||||||
unmerged = 0;
|
funny = 0;
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
struct cache_entry *ce = active_cache[i];
|
struct cache_entry *ce = active_cache[i];
|
||||||
if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
|
if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
|
||||||
if (++unmerged > 10) {
|
if (10 < ++funny) {
|
||||||
fprintf(stderr, "...\n");
|
fprintf(stderr, "...\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1));
|
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");
|
die("write-tree: not able to write tree");
|
||||||
|
|
||||||
/* Ok, write it out */
|
/* Ok, write it out */
|
||||||
|
|
Loading…
Reference in New Issue