Merge commit 'junio/master' into devel

Conflicts:
	Makefile
	builtin-clone.c
	t/t4109-apply-multifrag.sh
	t/t4110-apply-scan.sh
This commit is contained in:
Steffen Prohaska
2008-07-26 10:46:02 +02:00
310 changed files with 3927 additions and 2743 deletions

View File

@@ -5,22 +5,28 @@
# same person appearing not to be so.
#
Alexander Gavrilov <angavrilov@gmail.com>
Aneesh Kumar K.V <aneesh.kumar@gmail.com>
Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
Chris Shoemaker <c.shoemaker@cox.net>
Dana L. How <danahow@gmail.com>
Dana L. How <how@deathvalley.cswitch.com>
Daniel Barkalow <barkalow@iabervon.org>
David D. Kilzer <ddkilzer@kilzer.net>
David Kågedal <davidk@lysator.liu.se>
David S. Miller <davem@davemloft.net>
Dirk Süsserott <newsletter@dirk.my1.cc>
Fredrik Kuivinen <freku045@student.liu.se>
H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
H. Peter Anvin <hpa@tazenda.sc.orionmulti.com>
H. Peter Anvin <hpa@trantor.hos.anvin.org>
Horst H. von Brand <vonbrand@inf.utfsm.cl>
İsmail Dönmez <ismail@pardus.org.tr>
Jay Soffian <jaysoffian+git@gmail.com>
Joachim Berdal Haga <cjhaga@fys.uio.no>
Jon Loeliger <jdl@freescale.com>
Jon Seymour <jon@blackcubes.dyndns.org>
Jonathan Nieder <jrnieder@uchicago.edu>
Junio C Hamano <junio@twinsun.com>
Karl Hasselström <kha@treskal.com>
Kent Engstrom <kent@lysator.liu.se>
@@ -30,9 +36,12 @@ Li Hong <leehong@pku.edu.cn>
Lukas Sandström <lukass@etek.chalmers.se>
Martin Langhoff <martin@catalyst.net.nz>
Michael Coleman <tutufan@gmail.com>
Michael W. Olson <mwolson@gnu.org>
Michele Ballabio <barra_cuda@katamail.com>
Nanako Shiraishi <nanako3@bluebottle.com>
Nanako Shiraishi <nanako3@lavabit.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Philippe Bruhat <book@cpan.org>
Ramsay Allan Jones <ramsay@ramsay1.demon.co.uk>
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Robert Fitzsimons <robfitz@273k.net>

View File

@@ -105,7 +105,7 @@ For C programs:
- Use the API. No, really. We have a strbuf (variable length
string), several arrays with the ALLOC_GROW() macro, a
path_list for sorted string lists, a hash map (mapping struct
string_list for sorted string lists, a hash map (mapping struct
objects) named "struct decorate", amongst other things.
- When you come up with an API, document it.

View File

@@ -0,0 +1,47 @@
GIT v1.5.6.4 Release Notes
==========================
Fixes since v1.5.6.3
--------------------
* Various commands could overflow its internal buffer on a platform
with small PATH_MAX value in a repository that has contents with
long pathnames.
* There wasn't a way to make --pretty=format:%<> specifiers to honor
.mailmap name rewriting for authors and committers. Now you can with
%aN and %cN.
* Bash completion wasted too many cycles; this has been optimized to be
usable again.
* Bash completion lost ref part when completing something like "git show
pu:Makefile".
* "git-cvsserver" did not clean up its temporary working area after annotate
request.
* "git-daemon" called syslog() from its signal handler, which was a
no-no.
* "git-fetch" into an empty repository used to remind that the fetch will
be huge by saying "no common commits", but this was an unnecessary
noise; it is already known by the user anyway.
* "git-http-fetch" would have segfaulted when pack idx file retrieved
from the other side was corrupt.
* "git-index-pack" used too much memory when dealing with a deep delta chain.
* "git-mailinfo" (hence "git-am") did not correctly handle in-body [PATCH]
line to override the commit title taken from the mail Subject header.
* "git-rebase -i -p" lost parents that are not involved in the history
being rewritten.
* "git-rm" lost track of where the index file was when GIT_DIR was
specified as a relative path.
* "git-rev-list --quiet" was not quiet as advertised.
Contains other various documentation fixes.

View File

@@ -21,13 +21,19 @@ main git.git codebase.
By default, packfiles created with this version uses delta-base-offset
encoding introduced in v1.4.4. Pack idx files are using version 2 that
allows larger packs and added robustness thanks to its CRC checking,
introduced in v1.5.2.
introduced in v1.5.2 and v1.4.4.5. If you want to keep your repositories
backwards compatible past these versions, set repack.useDeltaBaseOffset
to false or pack.indexVersion to 1, respectively.
GIT_CONFIG, which was only documented as affecting "git config", but
actually affected all git commands, now only affects "git config".
GIT_LOCAL_CONFIG, also only documented as affecting "git config" and
not different from GIT_CONFIG in a useful way, is removed.
The ".dotest" temporary area "git am" and "git rebase" use is now moved
inside the $GIT_DIR, to avoid mistakes of adding it to the project by
accident.
An ancient merge strategy "stupid" has been removed.
@@ -67,7 +73,8 @@ Updates since v1.5.6
(performance, robustness, sanity etc.)
* even more documentation pages are now accessible via "man" and "git help".
* index-pack used too much memory when dealing with a deep delta chain.
This has been optimized.
* reduced excessive inlining to shrink size of the "git" binary.
@@ -79,6 +86,8 @@ Updates since v1.5.6
repack -a -f" can be used to fix such a corruption as long as necessary
objects are available.
* Performance of "git-blame -C -C" operation is vastly improved.
* git-clone does not create refs in loose form anymore (it behaves as
if you immediately ran git-pack-refs after cloning). This will help
repositories with insanely large number of refs.
@@ -92,6 +101,8 @@ Updates since v1.5.6
(usability, bells and whistles)
* even more documentation pages are now accessible via "man" and "git help".
* A new environment variable GIT_CEILING_DIRECTORIES can be used to stop
the discovery process of the toplevel of working tree; this may be useful
when you are working in a slow network disk and are outside any working tree,
@@ -125,6 +136,9 @@ Updates since v1.5.6
* git-archive can be told to omit certain paths from its output using
export-ignore attributes.
* git-archive uses the zlib default compression level when creating
zip archive.
* With -v option, git-branch describes the remote tracking statistics
similar to the way git-checkout reports by how many commits your branch
is ahead/behind.
@@ -144,6 +158,8 @@ Updates since v1.5.6
* git-clone can clone from a remote whose URL would be rewritten by
configuration stored in $HOME/.gitconfig now.
* git-cvsserver learned to respond to "cvs co -c".
* git-diff --check now checks leftover merge conflict markers.
* When remote side used to have branch 'foo' and git-fetch finds that now
@@ -155,6 +171,8 @@ Updates since v1.5.6
* fast-export learned to export and import marks file; this can be used to
interface with fast-import incrementally.
* fast-import and fast-export learned to export and import gitlinks.
* git-rebase records the original tip of branch in ORIG_HEAD before it is
rewound.
@@ -188,6 +206,8 @@ Updates since v1.5.6
(internal)
* git-merge has been reimplemented in C.
Fixes since v1.5.6
------------------
@@ -195,12 +215,8 @@ Fixes since v1.5.6
All of the fixes in v1.5.6 maintenance series are included in
this release, unless otherwise noted.
* "git fetch" into an empty repository used to remind the fetch will
be huge by saying "no common commits", but it is already known by
the user anyway (need to backport 8cb560f to 'maint').
---
exec >/var/tmp/1
O=v1.5.6.3-350-g499027b
O=v1.5.6.4-432-g6796399
echo O=$(git describe refs/heads/master)
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint

View File

@@ -301,7 +301,7 @@ If it does not apply correctly, there can be various reasons.
patch appropriately.
* Your MUA corrupted your patch; "am" would complain that
the patch does not apply. Look at .git/rebase/ subdirectory and
the patch does not apply. Look at .git/rebase-apply/ subdirectory and
see what 'patch' file contains and check for the common
corruption patterns mentioned above.

View File

@@ -358,7 +358,8 @@ core.whitespace::
A comma separated list of common whitespace problems to
notice. 'git-diff' will use `color.diff.whitespace` to
highlight them, and 'git-apply --whitespace=error' will
consider them as errors:
consider them as errors. You can prefix `-` to disable
any of them (e.g. `-trailing-space`):
+
* `trailing-space` treats trailing whitespaces at the end of the line
as an error (enabled by default).

View File

@@ -96,7 +96,7 @@ index fabadb8,cc95eb0..4866510
+
or like this (when '--cc' option is used):
diff --c file
diff --cc file
2. It is followed by one or more extended header lines
(this example shows a merge with two parents):

View File

@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
[--update | -u] [--refresh] [--ignore-errors] [--]
[--all | [--update | -u]] [--refresh] [--ignore-errors] [--]
<filepattern>...
DESCRIPTION
@@ -86,6 +86,12 @@ OPTIONS
command line. If no paths are specified, all tracked files in the
current directory and its subdirectories are updated.
-A::
--all::
Update files that git already knows about (same as '\--update')
and add all untracked files that are not ignored by '.gitignore'
mechanism.
--refresh::
Don't add the file(s), but only refresh their stat()
information in the index.

View File

@@ -13,7 +13,7 @@ SYNOPSIS
[--3way] [--interactive] [--binary]
[--whitespace=<option>] [-C<n>] [-p<n>]
[<mbox> | <Maildir>...]
'git am' (--skip | --resolved)
'git am' (--skip | --resolved | --abort)
DESCRIPTION
-----------
@@ -99,6 +99,9 @@ default. You could use `--no-utf8` to override this.
or `--skip` to handle the failure. This is solely
for internal use between 'git-rebase' and 'git-am'.
--abort::
Restore the original branch and abort the patching operation.
DISCUSSION
----------
@@ -140,9 +143,9 @@ aborts in the middle,. You can recover from this in one of two ways:
the index file to bring it in a state that the patch should
have produced. Then run the command with '--resolved' option.
The command refuses to process new mailboxes while `.git/rebase`
The command refuses to process new mailboxes while `.git/rebase-apply`
directory exists, so if you decide to start over from scratch,
run `rm -f -r .git/rebase` before running the command with mailbox
run `rm -f -r .git/rebase-apply` before running the command with mailbox
names.
Before any patches are applied, ORIG_HEAD is set to the tip of the
@@ -159,7 +162,7 @@ linkgit:git-apply[1].
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -190,7 +190,7 @@ linkgit:git-annotate[1]
AUTHOR
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
GIT
---

View File

@@ -205,7 +205,7 @@ but different purposes:
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <junkio@cox.net>
Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -30,7 +30,7 @@ linkgit:gitattributes[5].
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
'git checkout' [<tree-ish>] <paths>...
'git checkout' [<tree-ish>] [--] <paths>...
DESCRIPTION
-----------

View File

@@ -58,14 +58,14 @@ OPTIONS
Usually the command automatically creates a commit with
a commit log message stating which commit was
cherry-picked. This flag applies the change necessary
to cherry-pick the named commit to your working tree,
but does not make the commit. In addition, when this
option is used, your working tree does not have to match
to cherry-pick the named commit to your working tree
and the index, but does not make the commit. In addition,
when this option is used, your index does not have to match
the HEAD commit. The cherry-pick is done against the
beginning state of your working tree.
beginning state of your index.
+
This is useful when cherry-picking more than one commits'
effect to your working tree in a row.
effect to your index in a row.
-s::
--signoff::
@@ -74,7 +74,7 @@ effect to your working tree in a row.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -64,7 +64,7 @@ linkgit:git-patch-id[1]
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -87,8 +87,8 @@ then the cloned repository will become corrupt.
--quiet::
-q::
Operate quietly. This flag is passed to "rsync" and
'git-fetch-pack' commands when given.
Operate quietly. This flag is also passed to the `rsync'
command when given.
--no-checkout::
-n::
@@ -113,9 +113,8 @@ then the cloned repository will become corrupt.
--upload-pack <upload-pack>::
-u <upload-pack>::
When given, and the repository to clone from is handled
by 'git-fetch-pack', `--exec=<upload-pack>` is passed to
the command to specify non-default path for the command
When given, and the repository to clone from is accessed
via ssh, this specifies a non-default path for the command
run on the other end.
--template=<template_directory>::

View File

@@ -331,7 +331,7 @@ linkgit:git-commit-tree[1]
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>
Junio C Hamano <gitster@pobox.com>
GIT

View File

@@ -27,7 +27,7 @@ OPTIONS
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -136,7 +136,7 @@ will be the smallest number of commits possible.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>, but somewhat
butchered by Junio C Hamano <junkio@cox.net>. Later significantly
butchered by Junio C Hamano <gitster@pobox.com>. Later significantly
updated by Shawn Pearce <spearce@spearce.org>.
Documentation

View File

@@ -93,11 +93,11 @@ include::pretty-options.txt[]
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output
by omitting hunks that show differences from only one
parent, or show the same change from all but one parent
for an Octopus merge. When this optimization makes all
hunks disappear, the commit itself and the commit log
message is not shown, just like in any other "empty diff" case.
by omitting uninteresting hunks whose the contents in the parents
have only two variants and the merge result picks one of them
without modification. When all hunks are uninteresting, the commit
itself and the commit log message is not shown, just like in any other
"empty diff" case.
--always::
Show the commit itself and the commit log message even

View File

@@ -481,6 +481,9 @@ in octal. Git only supports the following modes:
what you want.
* `100755` or `755`: A normal, but executable, file.
* `120000`: A symlink, the content of the file will be the link target.
* `160000`: A gitlink, SHA-1 of the object refers to a commit in
another repository. Git links can only be specified by SHA or through
a commit mark. They are used to implement submodules.
In both formats `<path>` is the complete path of the file to be added
(if not already existing) or modified (if already existing).

View File

@@ -45,7 +45,7 @@ linkgit:git-pull[1]
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>
Junio C Hamano <gitster@pobox.com>
Documentation
-------------

View File

@@ -191,7 +191,7 @@ Thus you may instead want to use `rm -f filename` as the script.
A significantly faster version:
--------------------------------------------------------------------------
git filter-branch --index-filter 'git update-index --remove filename' HEAD
git filter-branch --index-filter 'git rm --cached filename' HEAD
--------------------------------------------------------------------------
Now, you will get the rewritten history saved in HEAD.

View File

@@ -61,7 +61,7 @@ linkgit:git-merge[1]
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -235,7 +235,7 @@ linkgit:git-am[1], linkgit:git-send-email[1]
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -37,7 +37,7 @@ OPTIONS
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -69,7 +69,7 @@ EXAMPLES
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
GIT
---

View File

@@ -81,7 +81,7 @@ with minimum width of 7 characters. Object size is given only for blobs
Author
------
Written by Petr Baudis <pasky@suse.cz>
Completely rewritten from scratch by Junio C Hamano <junkio@cox.net>,
Completely rewritten from scratch by Junio C Hamano <gitster@pobox.com>,
another major rewrite by Linus Torvalds <torvalds@osdl.org>
Documentation

View File

@@ -60,7 +60,7 @@ conversion, even with this flag.
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>
Junio C Hamano <gitster@pobox.com>
Documentation

View File

@@ -46,7 +46,7 @@ OPTIONS
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
and Junio C Hamano <junkio@cox.net>
and Junio C Hamano <gitster@pobox.com>
Documentation

View File

@@ -18,7 +18,7 @@ to resolve a merge after the trivial merge done with 'git-read-tree -m'.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>,
Junio C Hamano <junkio@cox.net> and Petr Baudis <pasky@suse.cz>.
Junio C Hamano <gitster@pobox.com> and Petr Baudis <pasky@suse.cz>.
Documentation
--------------

View File

@@ -57,50 +57,31 @@ HOW MERGE WORKS
A merge is always between the current `HEAD` and one or more
commits (usually, branch head or tag), and the index file must
exactly match the
tree of `HEAD` commit (i.e. the contents of the last commit) when
it happens. In other words, `git diff --cached HEAD` must
report no changes.
match the tree of `HEAD` commit (i.e. the contents of the last commit)
when it starts out. In other words, `git diff --cached HEAD` must
report no changes. (One exception is when the changed index
entries are already in the same state that would result from
the merge anyway.)
[NOTE]
This is a bit of a lie. In certain special cases, your index is
allowed to be different from the tree of the `HEAD` commit. The most
notable case is when your `HEAD` commit is already ahead of what
is being merged, in which case your index can have arbitrary
differences from your `HEAD` commit. Also, your index entries
may have differences from your `HEAD` commit that match
the result of a trivial merge (e.g. you received the same patch
from an external source to produce the same result as what you are
merging). For example, if a path did not exist in the common
ancestor and your head commit but exists in the tree you are
merging into your repository, and if you already happen to have
that path exactly in your index, the merge does not have to
fail.
Three kinds of merge can happen:
Otherwise, merge will refuse to do any harm to your repository
(that is, it may fetch the objects from remote, and it may even
update the local branch used to keep track of the remote branch
with `git pull remote rbranch:lbranch`, but your working tree,
`.git/HEAD` pointer and index file are left intact). In addition,
merge always sets `.git/ORIG_HEAD` to the original state of HEAD so
a problematic merge can be removed by using `git reset ORIG_HEAD`.
* The merged commit is already contained in `HEAD`. This is the
simplest case, called "Already up-to-date."
You may have local modifications in the working tree files. In
other words, 'git-diff' is allowed to report changes.
However, the merge uses your working tree as the working area,
and in order to prevent the merge operation from losing such
changes, it makes sure that they do not interfere with the
merge. Those complex tables in read-tree documentation define
what it means for a path to "interfere with the merge". And if
your local modifications interfere with the merge, again, it
stops before touching anything.
* `HEAD` is already contained in the merged commit. This is the
most common case especially when involved through 'git pull':
you are tracking an upstream repository, committed no local
changes and now you want to update to a newer upstream revision.
Your `HEAD` (and the index) is updated to at point the merged
commit, without creating an extra merge commit. This is
called "Fast-forward".
So in the above two "failed merge" case, you do not have to
worry about loss of data --- you simply were not ready to do
a merge, so no merge happened at all. You may want to finish
whatever you were in the middle of doing, and retry the same
pull after you are done and ready.
* Both the merged commit and `HEAD` are independent and must be
tied together by a merge commit that has them both as its parents.
The rest of this section describes this "True merge" case.
The chosen merge strategy merges the two commits into a single
new source tree.
When things cleanly merge, these things happen:
1. The results are updated both in the index file and in your
@@ -142,12 +123,13 @@ After seeing a conflict, you can do two things:
* Decide not to merge. The only clean-up you need are to reset
the index file to the `HEAD` commit to reverse 2. and to clean
up working tree changes made by 2. and 3.; 'git-reset' can
up working tree changes made by 2. and 3.; 'git-reset --hard' can
be used for this.
* Resolve the conflicts. `git diff` would report only the
conflicting paths because of the above 2. and 3. Edit the
working tree files into a desirable shape, 'git-add' or 'git-rm'
conflicting paths because of the above 2. and 3.
Edit the working tree files into a desirable shape
('git mergetool' can ease this task), 'git-add' or 'git-rm'
them, to make the index file contain what the merge result
should be, and run 'git-commit' to commit the result.
@@ -163,7 +145,7 @@ linkgit:git-mergetool[1]
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation

View File

@@ -23,7 +23,7 @@ OPTIONS
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -39,7 +39,7 @@ OPTIONS
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -193,7 +193,7 @@ linkgit:git-fetch[1], linkgit:git-merge[1], linkgit:git-config[1]
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
and Junio C Hamano <junkio@cox.net>
and Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -195,7 +195,7 @@ git push origin master:refs/heads/experimental::
Author
------
Written by Junio C Hamano <junkio@cox.net>, later rewritten in C
Written by Junio C Hamano <gitster@pobox.com>, later rewritten in C
by Linus Torvalds <torvalds@osdl.org>
Documentation

View File

@@ -39,8 +39,8 @@ It is possible that a merge failure will prevent this process from being
completely automatic. You will have to resolve any such merge failure
and run `git rebase --continue`. Another option is to bypass the commit
that caused the merge failure with `git rebase --skip`. To restore the
original <branch> and remove the .git/rebase working files, use the command
`git rebase --abort` instead.
original <branch> and remove the .git/rebase-apply working files, use the
command `git rebase --abort` instead.
Assume the following history exists and the current branch is "topic":
@@ -398,7 +398,7 @@ after each commit, test, and amend the commit if fixes are necessary.
Authors
------
Written by Junio C Hamano <junkio@cox.net> and
Written by Junio C Hamano <gitster@pobox.com> and
Johannes E. Schindelin <johannes.schindelin@gmx.de>
Documentation

View File

@@ -94,7 +94,7 @@ them.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -28,7 +28,7 @@ OPTIONS
Author
------
Written by Ryan Anderson <ryan@michonline.com> and Junio C Hamano <junkio@cox.net>
Written by Ryan Anderson <ryan@michonline.com> and Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -37,7 +37,7 @@ its working state.
'clear'::
This resets the metadata used by rerere if a merge resolution is to be
is aborted. Calling 'git-am --skip' or 'git-rebase [--skip|--abort]'
aborted. Calling 'git-am [--skip|--abort]' or 'git-rebase [--skip|--abort]'
will automatically invoke this command.
'diff'::
@@ -204,7 +204,7 @@ conflict.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
GIT
---

View File

@@ -195,7 +195,7 @@ $ git add frotz.c <3>
Author
------
Written by Junio C Hamano <junkio@cox.net> and Linus Torvalds <torvalds@osdl.org>
Written by Junio C Hamano <gitster@pobox.com> and Linus Torvalds <torvalds@osdl.org>
Documentation
--------------

View File

@@ -426,7 +426,7 @@ but if $REV is empty, the commit object name from master will be printed.
Author
------
Written by Linus Torvalds <torvalds@osdl.org> .
Junio C Hamano <junkio@cox.net> and Pierre Habouzit <madcoder@debian.org>
Junio C Hamano <gitster@pobox.com> and Pierre Habouzit <madcoder@debian.org>
Documentation
--------------

View File

@@ -43,16 +43,16 @@ OPTIONS
-n::
--no-commit::
Usually the command automatically creates a commit with
a commit log message stating which commit was reverted.
This flag applies the change necessary to revert the
named commit to your working tree, but does not make the
commit. In addition, when this option is used, your
working tree does not have to match the HEAD commit.
The revert is done against the beginning state of your
working tree.
a commit log message stating which commit was
reverted. This flag applies the change necessary
to revert the named commit to your working tree
and the index, but does not make the commit. In addition,
when this option is used, your index does not have to match
the HEAD commit. The revert is done against the
beginning state of your index.
+
This is useful when reverting more than one commits'
effect to your working tree in a row.
effect to your index in a row.
-s::
--signoff::
@@ -61,7 +61,7 @@ effect to your working tree in a row.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -182,7 +182,7 @@ topologically related with each other.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation

View File

@@ -71,7 +71,7 @@ include::i18n.txt[]
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>. Significantly enhanced by
Junio C Hamano <gitster@pobox.com>. Significantly enhanced by
Johannes Schindelin <Johannes.Schindelin@gmx.de>.

View File

@@ -64,7 +64,7 @@ linkgit:gitignore[5]
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>.
Junio C Hamano <gitster@pobox.com>.
Documentation
--------------

View File

@@ -16,6 +16,48 @@ SYNOPSIS
'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
DESCRIPTION
-----------
Submodules allow foreign repositories to be embedded within
a dedicated subdirectory of the source tree, always pointed
at a particular commit.
They are not to be confused with remotes, which are meant mainly
for branches of the same project; submodules are meant for
different projects you would like to make part of your source tree,
while the history of the two projects still stays completely
independent and you cannot modify the contents of the submodule
from within the main project.
If you want to merge the project histories and want to treat the
aggregated whole as a single project from then on, you may want to
add a remote for the other project and use the 'subtree' merge strategy,
instead of treating the other project as a submodule. Directories
that come from both projects can be cloned and checked out as a whole
if you choose to go that route.
Submodules are composed from a so-called `gitlink` tree entry
in the main repository that refers to a particular commit object
within the inner repository that is completely separate.
A record in the `.gitmodules` file at the root of the source
tree assigns a logical name to the submodule and describes
the default URL the submodule shall be cloned from.
The logical name can be used for overriding this URL within your
local repository configuration (see 'submodule init').
This command will manage the tree entries and contents of the
gitmodules file for you, as well as inspect the status of your
submodules and update them.
When adding a new submodule to the tree, the 'add' subcommand
is to be used. However, when pulling a tree containing submodules,
these will not be checked out by default;
the 'init' and 'update' subcommands will maintain submodules
checked out and at appropriate revision in your working tree.
You can briefly inspect the up-to-date status of your submodules
using the 'status' subcommand and get a detailed overview of the
difference between the index and checkouts using the 'summary'
subcommand.
COMMANDS
--------
add::
@@ -56,10 +98,15 @@ status::
repository. This command is the default command for 'git-submodule'.
init::
Initialize the submodules, i.e. register in .git/config each submodule
name and url found in .gitmodules. The key used in .git/config is
`submodule.$name.url`. This command does not alter existing information
in .git/config.
Initialize the submodules, i.e. register each submodule name
and url found in .gitmodules into .git/config.
The key used in .git/config is `submodule.$name.url`.
This command does not alter existing information in .git/config.
You can then customize the submodule clone URLs in .git/config
for your local setup and proceed to 'git submodule update';
you can also just use 'git submodule update --init' without
the explicit 'init' step if you do not intend to customize
any submodule locations.
update::
Update the registered submodules, i.e. clone missing submodules and

View File

@@ -55,7 +55,7 @@ name is not a symbolic ref, or 128 if another error occurs.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
GIT
---

View File

@@ -9,7 +9,8 @@ git-tag - Create, list, delete or verify a tag object signed with GPG
SYNOPSIS
--------
[verse]
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <name> [<head>]
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
<name> [<commit> | <object>]
'git tag' -d <name>...
'git tag' [-n[<num>]] -l [<pattern>]
'git tag' -v <name>...
@@ -247,7 +248,7 @@ $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1
Author
------
Written by Linus Torvalds <torvalds@osdl.org>,
Junio C Hamano <junkio@cox.net> and Chris Wright <chrisw@osdl.org>.
Junio C Hamano <gitster@pobox.com> and Chris Wright <chrisw@osdl.org>.
Documentation
--------------

View File

@@ -88,6 +88,16 @@ OPTIONS
sometimes helpful when working with a big project on a
filesystem that has very slow lstat(2) system call
(e.g. cifs).
+
This option can be also used as a coarse file-level mechanism
to ignore uncommitted changes in tracked files (akin to what
`.gitignore` does for untracked files).
You should remember that an explicit 'git add' operation will
still cause the file to be refreshed from the working tree.
Git will fail (gracefully) in case it needs to modify this file
in the index e.g. when merging in a commit;
thus, in case the assumed-untracked file is changed upstream,
you will need to handle the situation manually.
-g::
--again::

View File

@@ -47,7 +47,7 @@ info/refs file unless `--force` flag is given.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -42,7 +42,7 @@ for objects that are deltified.
Author
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------

View File

@@ -67,7 +67,7 @@ git whatchanged --since="2 weeks ago" \-- gitk::
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>
Junio C Hamano <gitster@pobox.com>
Documentation

View File

@@ -43,12 +43,13 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v1.5.6.3/git.html[documentation for release 1.5.6.3]
* link:v1.5.6.4/git.html[documentation for release 1.5.6.4]
* release notes for
link:RelNotes-1.5.6.3.txt[1.5.6.3].
link:RelNotes-1.5.6.2.txt[1.5.6.2].
link:RelNotes-1.5.6.1.txt[1.5.6.1].
link:RelNotes-1.5.6.4.txt[1.5.6.4],
link:RelNotes-1.5.6.3.txt[1.5.6.3],
link:RelNotes-1.5.6.2.txt[1.5.6.2],
link:RelNotes-1.5.6.1.txt[1.5.6.1],
link:RelNotes-1.5.6.txt[1.5.6].
* link:v1.5.5.4/git.html[documentation for release 1.5.5.4]

View File

@@ -13,9 +13,14 @@ DESCRIPTION
-----------
A `gitignore` file specifies intentionally untracked files that
git should ignore. Each line in a `gitignore` file specifies a
pattern.
git should ignore.
Note that all the `gitignore` files really concern only files
that are not already tracked by git;
in order to ignore uncommitted changes in already tracked files,
please refer to the 'git update-index --assume-unchanged'
documentation.
Each line in a `gitignore` file specifies a pattern.
When deciding whether to ignore a path, git normally checks
`gitignore` patterns from multiple sources, with the following
order of precedence, from highest to lowest (within one level of

View File

@@ -1,4 +1,4 @@
From: Junio C Hamano <junkio@cox.net>
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
Subject: Re: sending changesets from the middle of a git tree

View File

@@ -1,6 +1,6 @@
Subject: [HOWTO] Using post-update hook
Message-ID: <7vy86o6usx.fsf@assigned-by-dhcp.cox.net>
From: Junio C Hamano <junkio@cox.net>
From: Junio C Hamano <gitster@pobox.com>
Date: Fri, 26 Aug 2005 18:19:10 -0700
Abstract: In this how-to article, JC talks about how he
uses the post-update hook to automate git documentation page

View File

@@ -1,4 +1,4 @@
From: Junio C Hamano <junkio@cox.net>
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [HOWTO] Reverting an existing commit
Abstract: In this article, JC gives a small real-life example of using

View File

@@ -1,4 +1,4 @@
From: Junio C Hamano <junkio@cox.net>
From: Junio C Hamano <gitster@pobox.com>
Subject: Separating topic branches
Abstract: In this article, JC describes how to separate topic branches.

View File

@@ -1,4 +1,4 @@
From: Junio C Hamano <junkio@cox.net> and Carl Baldwin <cnb@fc.hp.com>
From: Junio C Hamano <gitster@pobox.com> and Carl Baldwin <cnb@fc.hp.com>
Subject: control access to branches.
Date: Thu, 17 Nov 2005 23:55:32 -0800
Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>

View File

@@ -112,9 +112,9 @@ options may be given. See linkgit:git-diff-files[1] for more options.
--cc::
This flag implies the '-c' options and further compresses the
patch output by omitting hunks that show differences from only
one parent, or show the same change from all but one parent for
an Octopus merge.
patch output by omitting uninteresting hunks whose contents in
the parents have only two variants and the merge result picks
one of them without modification.
-r::

View File

@@ -1,126 +0,0 @@
path-list API
=============
The path_list API offers a data structure and functions to handle sorted
and unsorted string lists.
The name is a bit misleading, a path_list may store not only paths but
strings in general.
The caller:
. Allocates and clears a `struct path_list` variable.
. Initializes the members. You might want to set the flag `strdup_paths`
if the strings should be strdup()ed. For example, this is necessary
when you add something like git_path("..."), since that function returns
a static buffer that will change with the next call to git_path().
+
If you need something advanced, you can manually malloc() the `items`
member (you need this if you add things later) and you should set the
`nr` and `alloc` members in that case, too.
. Adds new items to the list, using `path_list_append` or `path_list_insert`.
. Can check if a string is in the list using `path_list_has_path` or
`unsorted_path_list_has_path` and get it from the list using
`path_list_lookup` for sorted lists.
. Can sort an unsorted list using `sort_path_list`.
. Finally it should free the list using `path_list_clear`.
Example:
----
struct path_list list;
int i;
memset(&list, 0, sizeof(struct path_list));
path_list_append("foo", &list);
path_list_append("bar", &list);
for (i = 0; i < list.nr; i++)
printf("%s\n", list.items[i].path)
----
NOTE: It is more efficient to build an unsorted list and sort it
afterwards, instead of building a sorted list (`O(n log n)` instead of
`O(n^2)`).
+
However, if you use the list to check if a certain string was added
already, you should not do that (using unsorted_path_list_has_path()),
because the complexity would be quadratic again (but with a worse factor).
Functions
---------
* General ones (works with sorted and unsorted lists as well)
`print_path_list`::
Dump a path_list to stdout, useful mainly for debugging purposes. It
can take an optional header argument and it writes out the
string-pointer pairs of the path_list, each one in its own line.
`path_list_clear`::
Free a path_list. The `path` pointer of the items will be freed in case
the `strdup_paths` member of the path_list is set. The second parameter
controls if the `util` pointer of the items should be freed or not.
* Functions for sorted lists only
`path_list_has_path`::
Determine if the path_list has a given string or not.
`path_list_insert`::
Insert a new element to the path_list. The returned pointer can be handy
if you want to write something to the `util` pointer of the
path_list_item containing the just added string.
+
Since this function uses xrealloc() (which die()s if it fails) if the
list needs to grow, it is safe not to check the pointer. I.e. you may
write `path_list_insert(...)->util = ...;`.
`path_list_lookup`::
Look up a given string in the path_list, returning the containing
path_list_item. If the string is not found, NULL is returned.
* Functions for unsorted lists only
`path_list_append`::
Append a new string to the end of the path_list.
`sort_path_list`::
Make an unsorted list sorted.
`unsorted_path_list_has_path`::
It's like `path_list_has_path()` but for unsorted lists.
+
This function needs to look through all items, as opposed to its
counterpart for sorted lists, which performs a binary search.
Data structures
---------------
* `struct path_list_item`
Represents an item of the list. The `path` member is a pointer to the
string, and you may use the `util` member for any purpose, if you want.
* `struct path_list`
Represents the list itself.
. The array of items are available via the `items` member.
. The `nr` member contains the number of items stored in the list.
. The `alloc` member is used to avoid reallocating at every insertion.
You should not tamper with it.
. Setting the `strdup_paths` member to 1 will strdup() the strings
before adding them, see above.

View File

@@ -30,7 +30,7 @@ Functions
start_command() followed by finish_command(). Takes a pointer
to a `struct child_process` that specifies the details.
`run_command_v_opt`, `run_command_v_opt_dir`, `run_command_v_opt_cd_env`::
`run_command_v_opt`, `run_command_v_opt_cd`, `run_command_v_opt_cd_env`::
Convenience functions that encapsulate a sequence of
start_command() followed by finish_command(). The argument argv

View File

@@ -0,0 +1,128 @@
string-list API
===============
The string_list API offers a data structure and functions to handle sorted
and unsorted string lists.
The 'string_list' struct used to be called 'path_list', but was renamed
because it is not specific to paths.
The caller:
. Allocates and clears a `struct string_list` variable.
. Initializes the members. You might want to set the flag `strdup_strings`
if the strings should be strdup()ed. For example, this is necessary
when you add something like git_path("..."), since that function returns
a static buffer that will change with the next call to git_path().
+
If you need something advanced, you can manually malloc() the `items`
member (you need this if you add things later) and you should set the
`nr` and `alloc` members in that case, too.
. Adds new items to the list, using `string_list_append` or
`string_list_insert`.
. Can check if a string is in the list using `string_list_has_string` or
`unsorted_string_list_has_string` and get it from the list using
`string_list_lookup` for sorted lists.
. Can sort an unsorted list using `sort_string_list`.
. Finally it should free the list using `string_list_clear`.
Example:
----
struct string_list list;
int i;
memset(&list, 0, sizeof(struct string_list));
string_list_append("foo", &list);
string_list_append("bar", &list);
for (i = 0; i < list.nr; i++)
printf("%s\n", list.items[i].string)
----
NOTE: It is more efficient to build an unsorted list and sort it
afterwards, instead of building a sorted list (`O(n log n)` instead of
`O(n^2)`).
+
However, if you use the list to check if a certain string was added
already, you should not do that (using unsorted_string_list_has_string()),
because the complexity would be quadratic again (but with a worse factor).
Functions
---------
* General ones (works with sorted and unsorted lists as well)
`print_string_list`::
Dump a string_list to stdout, useful mainly for debugging purposes. It
can take an optional header argument and it writes out the
string-pointer pairs of the string_list, each one in its own line.
`string_list_clear`::
Free a string_list. The `string` pointer of the items will be freed in
case the `strdup_strings` member of the string_list is set. The second
parameter controls if the `util` pointer of the items should be freed
or not.
* Functions for sorted lists only
`string_list_has_string`::
Determine if the string_list has a given string or not.
`string_list_insert`::
Insert a new element to the string_list. The returned pointer can be
handy if you want to write something to the `util` pointer of the
string_list_item containing the just added string.
+
Since this function uses xrealloc() (which die()s if it fails) if the
list needs to grow, it is safe not to check the pointer. I.e. you may
write `string_list_insert(...)->util = ...;`.
`string_list_lookup`::
Look up a given string in the string_list, returning the containing
string_list_item. If the string is not found, NULL is returned.
* Functions for unsorted lists only
`string_list_append`::
Append a new string to the end of the string_list.
`sort_string_list`::
Make an unsorted list sorted.
`unsorted_string_list_has_string`::
It's like `string_list_has_string()` but for unsorted lists.
+
This function needs to look through all items, as opposed to its
counterpart for sorted lists, which performs a binary search.
Data structures
---------------
* `struct string_list_item`
Represents an item of the list. The `string` member is a pointer to the
string, and you may use the `util` member for any purpose, if you want.
* `struct string_list`
Represents the list itself.
. The array of items are available via the `items` member.
. The `nr` member contains the number of items stored in the list.
. The `alloc` member is used to avoid reallocating at every insertion.
You should not tamper with it.
. Setting the `strdup_strings` member to 1 will strdup() the strings
before adding them, see above.

View File

@@ -2431,7 +2431,7 @@ $ git rebase origin
-------------------------------------------------
This will remove each of your commits from mywork, temporarily saving
them as patches (in a directory named ".git/rebase"), update mywork to
them as patches (in a directory named ".git/rebase-apply"), update mywork to
point at the latest version of origin, then apply each of the saved
patches to the new mywork. The result will look like:

View File

@@ -170,6 +170,16 @@ ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
# Among the variables below, these:
# gitexecdir
# template_dir
# htmldir
# ETC_GITCONFIG (but not sysconfdir)
# can be specified as a relative path ../some/where/else (which must begin
# with ../); this is interpreted as relative to $(bindir) and "git" at
# runtime figures out where they are based on the path to the executable.
# This can help installing the suite in a relocatable way.
prefix =
bindir = $(prefix)/bin
mandir = $(prefix)/share/man
@@ -205,7 +215,7 @@ GITWEB_FAVICON = git-favicon.png
GITWEB_SITE_HEADER =
GITWEB_SITE_FOOTER =
export prefix bindir gitexecdir sharedir htmldir sysconfdir
export prefix bindir sharedir htmldir sysconfdir
CC = gcc
AR = ar
@@ -283,7 +293,6 @@ PROGRAMS += git-pack-redundant$X
PROGRAMS += git-patch-id$X
PROGRAMS += git-receive-pack$X
PROGRAMS += git-send-pack$X
PROGRAMS += git-shell$X
PROGRAMS += git-show-index$X
PROGRAMS += git-unpack-file$X
PROGRAMS += git-update-server-info$X
@@ -324,6 +333,7 @@ endif
export PERL_PATH
LIB_FILE=libgit.a
COMPAT_LIB = compat/lib.a
XDIFF_LIB=xdiff/lib.a
LIB_H += archive.h
@@ -355,7 +365,7 @@ LIB_H += pack-refs.h
LIB_H += pack-revindex.h
LIB_H += parse-options.h
LIB_H += patch-ids.h
LIB_H += path-list.h
LIB_H += string-list.h
LIB_H += pkt-line.h
LIB_H += progress.h
LIB_H += quote.h
@@ -409,6 +419,7 @@ LIB_OBJS += diff-no-index.o
LIB_OBJS += diff-lib.o
LIB_OBJS += diff.o
LIB_OBJS += dir.o
LIB_OBJS += editor.o
LIB_OBJS += entry.o
LIB_OBJS += environment.o
LIB_OBJS += exec_cmd.o
@@ -436,7 +447,7 @@ LIB_OBJS += pager.o
LIB_OBJS += parse-options.o
LIB_OBJS += patch-delta.o
LIB_OBJS += patch-ids.o
LIB_OBJS += path-list.o
LIB_OBJS += string-list.o
LIB_OBJS += path.o
LIB_OBJS += pkt-line.o
LIB_OBJS += pretty.o
@@ -744,9 +755,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o compat/winansi.o
EXTLIBS += -lws2_32
X = .exe
X = .exe
NOEXECTEMPL = .noexec
gitexecdir = $(bindir)
gitexecdir = ../libexec/git-core
template_dir = ../share/git-core/templates/
ETC_GITCONFIG = ../etc/gitconfig
htmldir=../doc/git/html/
@@ -814,6 +825,7 @@ EXTLIBS += -lz
ifndef NO_POSIX_ONLY_PROGRAMS
PROGRAMS += git-daemon$X
PROGRAMS += git-imap-send$X
PROGRAMS += git-shell$X
endif
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
@@ -1209,6 +1221,12 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
$(COMPAT_LIB): $(COMPAT_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(COMPAT_OBJS)
git-shell$X: abspath.o ctype.o exec_cmd.o quote.o strbuf.o usage.o wrapper.o shell.o $(COMPAT_LIB)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(COMPAT_LIB)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
@@ -1254,8 +1272,12 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
echo "$$FLAGS" >GIT-CFLAGS; \
fi
# We need to apply sq twice, once to protect from the shell
# that runs GIT-BUILD-OPTIONS, and then again to protect it
# and the first level quoting from the shell that runs "echo".
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
@echo SHELL_PATH=\''$(SHELL_PATH_SQ)'\' >$@
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
### Detect Tck/Tk interpreter path changes
ifndef NO_TCLTK
@@ -1304,41 +1326,49 @@ check: common-cmds.h
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
remove-dashes:
./fixup-builtins $(BUILT_INS)
./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS)
### Installation rules
ifeq ($(firstword $(subst /, ,$(template_dir))),..)
template_instdir = $(gitexecdir)/$(template_dir)
template_instdir = $(bindir)/$(template_dir)
else
template_instdir = $(template_dir)
endif
export template_instdir
ifeq ($(firstword $(subst /, ,$(gitexecdir))),..)
gitexec_instdir = $(bindir)/$(gitexecdir)
else
gitexec_instdir = $(gitexecdir)
endif
gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
export gitexec_instdir
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
ifndef NO_TCLTK
$(MAKE) -C gitk-git install
$(MAKE) -C git-gui install
$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
endif
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
then \
ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' || \
cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
fi
$(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
ifneq (,$X)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
endif
./check_bindir 'z$(bindir_SQ)' 'z$(gitexecdir_SQ)' '$(DESTDIR_SQ)$(bindir_SQ)/git-shell$X'
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
if test "z$$bindir" != "z$$execdir"; \
then \
ln -f "$$bindir/git$X" "$$execdir/git$X" || \
cp "$$bindir/git$X" "$$execdir/git$X"; \
fi && \
{ $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" && ln "$$execdir/git$X" "$$execdir/$p" ;) } && \
$(RM) "$$execdir/git$X" && \
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
install-doc:
$(MAKE) -C Documentation install
@@ -1406,7 +1436,7 @@ distclean: clean
clean:
$(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
$(LIB_FILE) $(XDIFF_LIB)
$(LIB_FILE) $(XDIFF_LIB) $(COMPAT_LIB)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*

View File

@@ -66,3 +66,39 @@ const char *make_absolute_path(const char *path)
return buf;
}
static const char *get_pwd_cwd(void)
{
static char cwd[PATH_MAX + 1];
char *pwd;
struct stat cwd_stat, pwd_stat;
if (getcwd(cwd, PATH_MAX) == NULL)
return NULL;
pwd = getenv("PWD");
if (pwd && strcmp(pwd, cwd)) {
stat(cwd, &cwd_stat);
if (!stat(pwd, &pwd_stat) &&
pwd_stat.st_dev == cwd_stat.st_dev &&
pwd_stat.st_ino == cwd_stat.st_ino) {
strlcpy(cwd, pwd, PATH_MAX);
}
}
return cwd;
}
const char *make_nonrelative_path(const char *path)
{
static char buf[PATH_MAX + 1];
if (is_absolute_path(path)) {
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
} else {
const char *cwd = get_pwd_cwd();
if (!cwd)
die("Cannot determine the current working directory");
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
}
return buf;
}

View File

@@ -2,9 +2,7 @@
* Copyright (c) 2005, 2006 Rene Scharfe
*/
#include "cache.h"
#include "commit.h"
#include "tar.h"
#include "builtin.h"
#include "archive.h"
#define RECORDSIZE (512)
@@ -13,11 +11,7 @@
static char block[BLOCKSIZE];
static unsigned long offset;
static time_t archive_time;
static int tar_umask = 002;
static int verbose;
static const struct commit *commit;
static size_t base_len;
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
@@ -114,22 +108,24 @@ static unsigned int ustar_header_chksum(const struct ustar_header *header)
return chksum;
}
static int get_path_prefix(const struct strbuf *path, int maxlen)
static size_t get_path_prefix(const char *path, size_t pathlen, size_t maxlen)
{
int i = path->len;
size_t i = pathlen;
if (i > maxlen)
i = maxlen;
do {
i--;
} while (i > 0 && path->buf[i] != '/');
} while (i > 0 && path[i] != '/');
return i;
}
static void write_entry(const unsigned char *sha1, struct strbuf *path,
unsigned int mode, void *buffer, unsigned long size)
static int write_tar_entry(struct archiver_args *args,
const unsigned char *sha1, const char *path, size_t pathlen,
unsigned int mode, void *buffer, unsigned long size)
{
struct ustar_header header;
struct strbuf ext_header;
int err = 0;
memset(&header, 0, sizeof(header));
strbuf_init(&ext_header, 0);
@@ -143,8 +139,6 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
mode = 0100666;
sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
} else {
if (verbose)
fprintf(stderr, "%.*s\n", (int)path->len, path->buf);
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
*header.typeflag = TYPEFLAG_DIR;
mode = (mode | 0777) & ~tar_umask;
@@ -155,24 +149,24 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
*header.typeflag = TYPEFLAG_REG;
mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
} else {
error("unsupported file mode: 0%o (SHA1: %s)",
mode, sha1_to_hex(sha1));
return;
return error("unsupported file mode: 0%o (SHA1: %s)",
mode, sha1_to_hex(sha1));
}
if (path->len > sizeof(header.name)) {
int plen = get_path_prefix(path, sizeof(header.prefix));
int rest = path->len - plen - 1;
if (pathlen > sizeof(header.name)) {
size_t plen = get_path_prefix(path, pathlen,
sizeof(header.prefix));
size_t rest = pathlen - plen - 1;
if (plen > 0 && rest <= sizeof(header.name)) {
memcpy(header.prefix, path->buf, plen);
memcpy(header.name, path->buf + plen + 1, rest);
memcpy(header.prefix, path, plen);
memcpy(header.name, path + plen + 1, rest);
} else {
sprintf(header.name, "%s.data",
sha1_to_hex(sha1));
strbuf_append_ext_header(&ext_header, "path",
path->buf, path->len);
path, pathlen);
}
} else
memcpy(header.name, path->buf, path->len);
memcpy(header.name, path, pathlen);
}
if (S_ISLNK(mode) && buffer) {
@@ -187,7 +181,7 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
sprintf(header.mode, "%07o", mode & 07777);
sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
sprintf(header.mtime, "%011lo", archive_time);
sprintf(header.mtime, "%011lo", args->time);
sprintf(header.uid, "%07o", 0);
sprintf(header.gid, "%07o", 0);
@@ -202,22 +196,30 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
sprintf(header.chksum, "%07o", ustar_header_chksum(&header));
if (ext_header.len > 0) {
write_entry(sha1, NULL, 0, ext_header.buf, ext_header.len);
err = write_tar_entry(args, sha1, NULL, 0, 0, ext_header.buf,
ext_header.len);
if (err)
return err;
}
strbuf_release(&ext_header);
write_blocked(&header, sizeof(header));
if (S_ISREG(mode) && buffer && size > 0)
write_blocked(buffer, size);
return err;
}
static void write_global_extended_header(const unsigned char *sha1)
static int write_global_extended_header(struct archiver_args *args)
{
const unsigned char *sha1 = args->commit_sha1;
struct strbuf ext_header;
int err;
strbuf_init(&ext_header, 0);
strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
write_entry(NULL, NULL, 0, ext_header.buf, ext_header.len);
err = write_tar_entry(args, NULL, NULL, 0, 0, ext_header.buf,
ext_header.len);
strbuf_release(&ext_header);
return err;
}
static int git_tar_config(const char *var, const char *value, void *cb)
@@ -234,64 +236,17 @@ static int git_tar_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
static int write_tar_entry(const unsigned char *sha1,
const char *base, int baselen,
const char *filename, unsigned mode, int stage)
{
static struct strbuf path = STRBUF_INIT;
void *buffer;
enum object_type type;
unsigned long size;
strbuf_reset(&path);
strbuf_grow(&path, PATH_MAX);
strbuf_add(&path, base, baselen);
strbuf_addstr(&path, filename);
if (is_archive_path_ignored(path.buf + base_len))
return 0;
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
strbuf_addch(&path, '/');
buffer = NULL;
size = 0;
} else {
buffer = sha1_file_to_archive(path.buf + base_len, sha1, mode,
&type, &size, commit);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
}
write_entry(sha1, &path, mode, buffer, size);
free(buffer);
return READ_TREE_RECURSIVE;
}
int write_tar_archive(struct archiver_args *args)
{
int plen = args->base ? strlen(args->base) : 0;
int err = 0;
git_config(git_tar_config, NULL);
archive_time = args->time;
verbose = args->verbose;
commit = args->commit;
base_len = args->base ? strlen(args->base) : 0;
if (args->commit_sha1)
write_global_extended_header(args->commit_sha1);
if (args->base && plen > 0 && args->base[plen - 1] == '/') {
char *base = xstrdup(args->base);
int baselen = strlen(base);
while (baselen > 0 && base[baselen - 1] == '/')
base[--baselen] = '\0';
write_tar_entry(args->tree->object.sha1, "", 0, base, 040777, 0);
free(base);
}
read_tree_recursive(args->tree, args->base, plen, 0,
args->pathspec, write_tar_entry);
write_trailer();
return 0;
err = write_global_extended_header(args);
if (!err)
err = write_archive_entries(args, write_tar_entry);
if (!err)
write_trailer();
return err;
}

View File

@@ -2,18 +2,10 @@
* Copyright (c) 2006 Rene Scharfe
*/
#include "cache.h"
#include "commit.h"
#include "blob.h"
#include "tree.h"
#include "quote.h"
#include "builtin.h"
#include "archive.h"
static int verbose;
static int zip_date;
static int zip_time;
static const struct commit *commit;
static size_t base_len;
static unsigned char *zip_dir;
static unsigned int zip_dir_size;
@@ -96,7 +88,7 @@ static void copy_le32(unsigned char *dest, unsigned int n)
}
static void *zlib_deflate(void *data, unsigned long size,
unsigned long *compressed_size)
int compression_level, unsigned long *compressed_size)
{
z_stream stream;
unsigned long maxsize;
@@ -104,7 +96,7 @@ static void *zlib_deflate(void *data, unsigned long size,
int result;
memset(&stream, 0, sizeof(stream));
deflateInit(&stream, zlib_compression_level);
deflateInit(&stream, compression_level);
maxsize = deflateBound(&stream, size);
buffer = xmalloc(maxsize);
@@ -128,33 +120,9 @@ static void *zlib_deflate(void *data, unsigned long size,
return buffer;
}
static char *construct_path(const char *base, int baselen,
const char *filename, int isdir, int *pathlen)
{
int filenamelen = strlen(filename);
int len = baselen + filenamelen;
char *path, *p;
if (isdir)
len++;
p = path = xmalloc(len + 1);
memcpy(p, base, baselen);
p += baselen;
memcpy(p, filename, filenamelen);
p += filenamelen;
if (isdir)
*p++ = '/';
*p = '\0';
*pathlen = len;
return path;
}
static int write_zip_entry(const unsigned char *sha1,
const char *base, int baselen,
const char *filename, unsigned mode, int stage)
static int write_zip_entry(struct archiver_args *args,
const unsigned char *sha1, const char *path, size_t pathlen,
unsigned int mode, void *buffer, unsigned long size)
{
struct zip_local_header header;
struct zip_dir_header dirent;
@@ -163,33 +131,20 @@ static int write_zip_entry(const unsigned char *sha1,
unsigned long uncompressed_size;
unsigned long crc;
unsigned long direntsize;
unsigned long size;
int method;
int result = -1;
int pathlen;
unsigned char *out;
char *path;
enum object_type type;
void *buffer = NULL;
void *deflated = NULL;
crc = crc32(0, NULL, 0);
path = construct_path(base, baselen, filename, S_ISDIR(mode), &pathlen);
if (is_archive_path_ignored(path + base_len))
return 0;
if (verbose)
fprintf(stderr, "%s\n", path);
if (pathlen > 0xffff) {
error("path too long (%d chars, SHA1: %s): %s", pathlen,
sha1_to_hex(sha1), path);
goto out;
return error("path too long (%d chars, SHA1: %s): %s",
(int)pathlen, sha1_to_hex(sha1), path);
}
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
method = 0;
attr2 = 16;
result = (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
out = NULL;
uncompressed_size = 0;
compressed_size = 0;
@@ -197,25 +152,20 @@ static int write_zip_entry(const unsigned char *sha1,
method = 0;
attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
(mode & 0111) ? ((mode) << 16) : 0;
if (S_ISREG(mode) && zlib_compression_level != 0)
if (S_ISREG(mode) && args->compression_level != 0)
method = 8;
result = 0;
buffer = sha1_file_to_archive(path + base_len, sha1, mode,
&type, &size, commit);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
crc = crc32(crc, buffer, size);
out = buffer;
uncompressed_size = size;
compressed_size = size;
} else {
error("unsupported file mode: 0%o (SHA1: %s)", mode,
sha1_to_hex(sha1));
goto out;
return error("unsupported file mode: 0%o (SHA1: %s)", mode,
sha1_to_hex(sha1));
}
if (method == 8) {
deflated = zlib_deflate(buffer, size, &compressed_size);
deflated = zlib_deflate(buffer, size, args->compression_level,
&compressed_size);
if (deflated && compressed_size - 6 < size) {
/* ZLIB --> raw compressed data (see RFC 1950) */
/* CMF and FLG ... */
@@ -278,12 +228,9 @@ static int write_zip_entry(const unsigned char *sha1,
zip_offset += compressed_size;
}
out:
free(buffer);
free(deflated);
free(path);
return result;
return 0;
}
static void write_zip_trailer(const unsigned char *sha1)
@@ -316,43 +263,18 @@ static void dos_time(time_t *time, int *dos_date, int *dos_time)
int write_zip_archive(struct archiver_args *args)
{
int plen = strlen(args->base);
int err;
dos_time(&args->time, &zip_date, &zip_time);
zip_dir = xmalloc(ZIP_DIRECTORY_MIN_SIZE);
zip_dir_size = ZIP_DIRECTORY_MIN_SIZE;
verbose = args->verbose;
commit = args->commit;
base_len = args->base ? strlen(args->base) : 0;
if (args->base && plen > 0 && args->base[plen - 1] == '/') {
char *base = xstrdup(args->base);
int baselen = strlen(base);
while (baselen > 0 && base[baselen - 1] == '/')
base[--baselen] = '\0';
write_zip_entry(args->tree->object.sha1, "", 0, base, 040777, 0);
free(base);
}
read_tree_recursive(args->tree, args->base, plen, 0,
args->pathspec, write_zip_entry);
write_zip_trailer(args->commit_sha1);
err = write_archive_entries(args, write_zip_entry);
if (!err)
write_zip_trailer(args->commit_sha1);
free(zip_dir);
return 0;
}
void *parse_extra_zip_args(int argc, const char **argv)
{
for (; argc > 0; argc--, argv++) {
const char *arg = argv[0];
if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0')
zlib_compression_level = arg[1] - '0';
else
die("Unknown argument for zip format: %s", arg);
}
return NULL;
return err;
}

291
archive.c
View File

@@ -1,6 +1,22 @@
#include "cache.h"
#include "commit.h"
#include "tree-walk.h"
#include "attr.h"
#include "archive.h"
static const char archive_usage[] = \
"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
#define USES_ZLIB_COMPRESSION 1
const struct archiver {
const char *name;
write_archive_fn_t write_archive;
unsigned int flags;
} archivers[] = {
{ "tar", write_tar_archive },
{ "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
};
static void format_subst(const struct commit *commit,
const char *src, size_t len,
@@ -35,34 +51,9 @@ static void format_subst(const struct commit *commit,
free(to_free);
}
static int convert_to_archive(const char *path,
const void *src, size_t len,
struct strbuf *buf,
const struct commit *commit)
{
static struct git_attr *attr_export_subst;
struct git_attr_check check[1];
if (!commit)
return 0;
if (!attr_export_subst)
attr_export_subst = git_attr("export-subst", 12);
check[0].attr = attr_export_subst;
if (git_checkattr(path, ARRAY_SIZE(check), check))
return 0;
if (!ATTR_TRUE(check[0].value))
return 0;
format_subst(commit, src, len, buf);
return 1;
}
void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *sizep,
const struct commit *commit)
static void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *sizep, const struct commit *commit)
{
void *buffer;
@@ -74,7 +65,8 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
strbuf_init(&buf, 0);
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
convert_to_working_tree(path, buf.buf, buf.len, &buf);
convert_to_archive(path, buf.buf, buf.len, &buf, commit);
if (commit)
format_subst(commit, buf.buf, buf.len, &buf);
buffer = strbuf_detach(&buf, &size);
*sizep = size;
}
@@ -82,16 +74,243 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
return buffer;
}
int is_archive_path_ignored(const char *path)
static void setup_archive_check(struct git_attr_check *check)
{
static struct git_attr *attr_export_ignore;
struct git_attr_check check[1];
static struct git_attr *attr_export_subst;
if (!attr_export_ignore)
if (!attr_export_ignore) {
attr_export_ignore = git_attr("export-ignore", 13);
attr_export_subst = git_attr("export-subst", 12);
}
check[0].attr = attr_export_ignore;
if (git_checkattr(path, ARRAY_SIZE(check), check))
return 0;
return ATTR_TRUE(check[0].value);
check[1].attr = attr_export_subst;
}
struct archiver_context {
struct archiver_args *args;
write_archive_entry_fn_t write_entry;
};
static int write_archive_entry(const unsigned char *sha1, const char *base,
int baselen, const char *filename, unsigned mode, int stage,
void *context)
{
static struct strbuf path = STRBUF_INIT;
struct archiver_context *c = context;
struct archiver_args *args = c->args;
write_archive_entry_fn_t write_entry = c->write_entry;
struct git_attr_check check[2];
const char *path_without_prefix;
int convert = 0;
int err;
enum object_type type;
unsigned long size;
void *buffer;
strbuf_reset(&path);
strbuf_grow(&path, PATH_MAX);
strbuf_add(&path, base, baselen);
strbuf_addstr(&path, filename);
path_without_prefix = path.buf + args->baselen;
setup_archive_check(check);
if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
if (ATTR_TRUE(check[0].value))
return 0;
convert = ATTR_TRUE(check[1].value);
}
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
strbuf_addch(&path, '/');
if (args->verbose)
fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
err = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);
if (err)
return err;
return READ_TREE_RECURSIVE;
}
buffer = sha1_file_to_archive(path_without_prefix, sha1, mode,
&type, &size, convert ? args->commit : NULL);
if (!buffer)
return error("cannot read %s", sha1_to_hex(sha1));
if (args->verbose)
fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
err = write_entry(args, sha1, path.buf, path.len, mode, buffer, size);
free(buffer);
return err;
}
int write_archive_entries(struct archiver_args *args,
write_archive_entry_fn_t write_entry)
{
struct archiver_context context;
int err;
if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
size_t len = args->baselen;
while (len > 1 && args->base[len - 2] == '/')
len--;
if (args->verbose)
fprintf(stderr, "%.*s\n", (int)len, args->base);
err = write_entry(args, args->tree->object.sha1, args->base,
len, 040777, NULL, 0);
if (err)
return err;
}
context.args = args;
context.write_entry = write_entry;
err = read_tree_recursive(args->tree, args->base, args->baselen, 0,
args->pathspec, write_archive_entry, &context);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
}
static const struct archiver *lookup_archiver(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(archivers); i++) {
if (!strcmp(name, archivers[i].name))
return &archivers[i];
}
return NULL;
}
static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
{
ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
}
static void parse_treeish_arg(const char **argv,
struct archiver_args *ar_args, const char *prefix)
{
const char *name = argv[0];
const unsigned char *commit_sha1;
time_t archive_time;
struct tree *tree;
const struct commit *commit;
unsigned char sha1[20];
if (get_sha1(name, sha1))
die("Not a valid object name");
commit = lookup_commit_reference_gently(sha1, 1);
if (commit) {
commit_sha1 = commit->object.sha1;
archive_time = commit->date;
} else {
commit_sha1 = NULL;
archive_time = time(NULL);
}
tree = parse_tree_indirect(sha1);
if (tree == NULL)
die("not a tree object");
if (prefix) {
unsigned char tree_sha1[20];
unsigned int mode;
int err;
err = get_tree_entry(tree->object.sha1, prefix,
tree_sha1, &mode);
if (err || !S_ISDIR(mode))
die("current working directory is untracked");
tree = parse_tree_indirect(tree_sha1);
}
ar_args->tree = tree;
ar_args->commit_sha1 = commit_sha1;
ar_args->commit = commit;
ar_args->time = archive_time;
}
static int parse_archive_args(int argc, const char **argv,
const struct archiver **ar, struct archiver_args *args)
{
const char *format = "tar";
const char *base = "";
int compression_level = -1;
int verbose = 0;
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
for (i = 0; i < ARRAY_SIZE(archivers); i++)
printf("%s\n", archivers[i].name);
exit(0);
}
if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
verbose = 1;
continue;
}
if (!prefixcmp(arg, "--format=")) {
format = arg + 9;
continue;
}
if (!prefixcmp(arg, "--prefix=")) {
base = arg + 9;
continue;
}
if (!strcmp(arg, "--")) {
i++;
break;
}
if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0') {
compression_level = arg[1] - '0';
continue;
}
if (arg[0] == '-')
die("Unknown argument: %s", arg);
break;
}
/* We need at least one parameter -- tree-ish */
if (argc - 1 < i)
usage(archive_usage);
*ar = lookup_archiver(format);
if (!*ar)
die("Unknown archive format '%s'", format);
args->compression_level = Z_DEFAULT_COMPRESSION;
if (compression_level != -1) {
if ((*ar)->flags & USES_ZLIB_COMPRESSION)
args->compression_level = compression_level;
else {
die("Argument not supported for format '%s': -%d",
format, compression_level);
}
}
args->verbose = verbose;
args->base = base;
args->baselen = strlen(base);
return i;
}
int write_archive(int argc, const char **argv, const char *prefix,
int setup_prefix)
{
const struct archiver *ar = NULL;
struct archiver_args args;
int tree_idx;
tree_idx = parse_archive_args(argc, argv, &ar, &args);
if (setup_prefix && prefix == NULL)
prefix = setup_git_directory();
argv += tree_idx;
parse_treeish_arg(argv, &args, prefix);
parse_pathspec_arg(argv + 1, &args);
return ar->write_archive(&args);
}

View File

@@ -1,49 +1,29 @@
#ifndef ARCHIVE_H
#define ARCHIVE_H
#define MAX_EXTRA_ARGS 32
#define MAX_ARGS (MAX_EXTRA_ARGS + 32)
struct archiver_args {
const char *base;
size_t baselen;
struct tree *tree;
const unsigned char *commit_sha1;
const struct commit *commit;
time_t time;
const char **pathspec;
unsigned int verbose : 1;
void *extra;
int compression_level;
};
typedef int (*write_archive_fn_t)(struct archiver_args *);
typedef void *(*parse_extra_args_fn_t)(int argc, const char **argv);
typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
struct archiver {
const char *name;
struct archiver_args args;
write_archive_fn_t write_archive;
parse_extra_args_fn_t parse_extra;
};
extern int parse_archive_args(int argc,
const char **argv,
struct archiver *ar);
extern void parse_treeish_arg(const char **treeish,
struct archiver_args *ar_args,
const char *prefix);
extern void parse_pathspec_arg(const char **pathspec,
struct archiver_args *args);
/*
* Archive-format specific backends.
*/
extern int write_tar_archive(struct archiver_args *);
extern int write_zip_archive(struct archiver_args *);
extern void *parse_extra_zip_args(int argc, const char **argv);
extern void *sha1_file_to_archive(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size, const struct commit *commit);
extern int is_archive_path_ignored(const char *path);
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix);
#endif /* ARCHIVE_H */

15
attr.c
View File

@@ -459,7 +459,9 @@ static void prepare_attr_stack(const char *path, int dirlen)
{
struct attr_stack *elem, *info;
int len;
char pathbuf[PATH_MAX];
struct strbuf pathbuf;
strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
/*
* At the bottom of the attribute stack is the built-in
@@ -510,13 +512,14 @@ static void prepare_attr_stack(const char *path, int dirlen)
len = strlen(attr_stack->origin);
if (dirlen <= len)
break;
memcpy(pathbuf, path, dirlen);
memcpy(pathbuf + dirlen, "/", 2);
cp = strchr(pathbuf + len + 1, '/');
strbuf_reset(&pathbuf);
strbuf_add(&pathbuf, path, dirlen);
strbuf_addch(&pathbuf, '/');
cp = strchr(pathbuf.buf + len + 1, '/');
strcpy(cp + 1, GITATTRIBUTES_FILE);
elem = read_attr(pathbuf, 0);
elem = read_attr(pathbuf.buf, 0);
*cp = '\0';
elem->origin = strdup(pathbuf);
elem->origin = strdup(pathbuf.buf);
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);

View File

@@ -16,7 +16,7 @@
#include "parse-options.h"
static const char * const builtin_add_usage[] = {
"git-add [options] [--] <filepattern>...",
"git add [options] [--] <filepattern>...",
NULL
};
static int patch_interactive = 0, add_interactive = 0;
@@ -140,9 +140,8 @@ static void refresh(int verbose, const char **pathspec)
for (specs = 0; pathspec[specs]; specs++)
/* nothing */;
seen = xcalloc(specs, 1);
if (read_cache() < 0)
die("index file corrupt");
refresh_index(&the_index, verbose ? 0 : REFRESH_QUIET, pathspec, seen);
refresh_index(&the_index, verbose ? REFRESH_SAY_CHANGED : REFRESH_QUIET,
pathspec, seen);
for (i = 0; i < specs; i++) {
if (!seen[i])
die("pathspec '%s' did not match any files", pathspec[i]);
@@ -192,7 +191,7 @@ static const char ignore_error[] =
"The following paths are ignored by one of your .gitignore files:\n";
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
static int ignore_add_errors;
static int ignore_add_errors, addremove;
static struct option builtin_add_options[] = {
OPT__DRY_RUN(&show_only),
@@ -202,6 +201,7 @@ static struct option builtin_add_options[] = {
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactive patching"),
OPT_BOOLEAN('f', "force", &ignored_too, "allow adding otherwise ignored files"),
OPT_BOOLEAN('u', "update", &take_worktree_changes, "update tracked files"),
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
OPT_END(),
@@ -216,13 +216,36 @@ static int add_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
static int add_files(struct dir_struct *dir, int flags)
{
int i, exit_status = 0;
if (dir->ignored_nr) {
fprintf(stderr, ignore_error);
for (i = 0; i < dir->ignored_nr; i++)
fprintf(stderr, "%s\n", dir->ignored[i]->name);
fprintf(stderr, "Use -f if you really want to add them.\n");
die("no files added");
}
for (i = 0; i < dir->nr; i++)
if (add_file_to_cache(dir->entries[i]->name, flags)) {
if (!ignore_add_errors)
die("adding files failed");
exit_status = 1;
}
return exit_status;
}
int cmd_add(int argc, const char **argv, const char *prefix)
{
int exit_status = 0;
int i, newfd;
int newfd;
const char **pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
int require_pathspec;
argc = parse_options(argc, argv, builtin_add_options,
builtin_add_usage, 0);
@@ -233,53 +256,51 @@ int cmd_add(int argc, const char **argv, const char *prefix)
git_config(add_config, NULL);
if (addremove && take_worktree_changes)
die("-A and -u are mutually incompatible");
if (addremove && !argc) {
static const char *here[2] = { ".", NULL };
argc = 1;
argv = here;
}
add_new_files = !take_worktree_changes && !refresh_only;
require_pathspec = !take_worktree_changes;
newfd = hold_locked_index(&lock_file, 1);
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
(show_only ? ADD_CACHE_PRETEND : 0) |
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0));
if (take_worktree_changes) {
const char **pathspec;
if (read_cache() < 0)
die("index file corrupt");
pathspec = get_pathspec(prefix, argv);
exit_status = add_files_to_cache(prefix, pathspec, flags);
goto finish;
}
if (argc == 0) {
if (require_pathspec && argc == 0) {
fprintf(stderr, "Nothing specified, nothing added.\n");
fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
return 0;
}
pathspec = get_pathspec(prefix, argv);
/*
* If we are adding new files, we need to scan the working
* tree to find the ones that match pathspecs; this needs
* to be done before we read the index.
*/
if (add_new_files)
fill_directory(&dir, pathspec, ignored_too);
if (read_cache() < 0)
die("index file corrupt");
if (refresh_only) {
refresh(verbose, pathspec);
goto finish;
}
fill_directory(&dir, pathspec, ignored_too);
if (take_worktree_changes || addremove)
exit_status |= add_files_to_cache(prefix, pathspec, flags);
if (read_cache() < 0)
die("index file corrupt");
if (dir.ignored_nr) {
fprintf(stderr, ignore_error);
for (i = 0; i < dir.ignored_nr; i++) {
fprintf(stderr, "%s\n", dir.ignored[i]->name);
}
fprintf(stderr, "Use -f if you really want to add them.\n");
die("no files added");
}
for (i = 0; i < dir.nr; i++)
if (add_file_to_cache(dir.entries[i]->name, flags)) {
if (!ignore_add_errors)
die("adding files failed");
exit_status = 1;
}
if (add_new_files)
exit_status |= add_files(&dir, flags);
finish:
if (active_cache_changed) {

View File

@@ -12,7 +12,7 @@
#include "blob.h"
#include "delta.h"
#include "builtin.h"
#include "path-list.h"
#include "string-list.h"
/*
* --check turns on checking that the working tree matches the
@@ -46,7 +46,7 @@ static const char *fake_ancestor;
static int line_termination = '\n';
static unsigned long p_context = ULONG_MAX;
static const char apply_usage[] =
"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>...";
"git apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>...";
static enum ws_error_action {
nowarn_ws_error,
@@ -194,7 +194,7 @@ struct image {
* the case where more than one patches touch the same file.
*/
static struct path_list fn_table;
static struct string_list fn_table;
static uint32_t hash_line(const char *cp, size_t len)
{
@@ -2250,12 +2250,12 @@ static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
static struct patch *in_fn_table(const char *name)
{
struct path_list_item *item;
struct string_list_item *item;
if (name == NULL)
return NULL;
item = path_list_lookup(name, &fn_table);
item = string_list_lookup(name, &fn_table);
if (item != NULL)
return (struct patch *)item->util;
@@ -2264,7 +2264,7 @@ static struct patch *in_fn_table(const char *name)
static void add_to_fn_table(struct patch *patch)
{
struct path_list_item *item;
struct string_list_item *item;
/*
* Always add new_name unless patch is a deletion
@@ -2272,7 +2272,7 @@ static void add_to_fn_table(struct patch *patch)
* file creations and copies
*/
if (patch->new_name != NULL) {
item = path_list_insert(patch->new_name, &fn_table);
item = string_list_insert(patch->new_name, &fn_table);
item->util = patch;
}
@@ -2281,7 +2281,7 @@ static void add_to_fn_table(struct patch *patch)
* later chunks shouldn't patch old names
*/
if ((patch->new_name == NULL) || (patch->is_rename)) {
item = path_list_insert(patch->old_name, &fn_table);
item = string_list_insert(patch->old_name, &fn_table);
item->util = (struct patch *) -1;
}
}
@@ -3051,7 +3051,7 @@ static int apply_patch(int fd, const char *filename, int options)
int skipped_patch = 0;
/* FIXME - memory leak when using multiple patch files as inputs */
memset(&fn_table, 0, sizeof(struct path_list));
memset(&fn_table, 0, sizeof(struct string_list));
strbuf_init(&buf, 0);
patch_input_file = filename;
read_patch_file(&buf, fd);

View File

@@ -5,25 +5,8 @@
#include "cache.h"
#include "builtin.h"
#include "archive.h"
#include "commit.h"
#include "tree-walk.h"
#include "exec_cmd.h"
#include "pkt-line.h"
#include "sideband.h"
#include "attr.h"
static const char archive_usage[] = \
"git-archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
static struct archiver_desc
{
const char *name;
write_archive_fn_t write_archive;
parse_extra_args_fn_t parse_extra;
} archivers[] = {
{ "tar", write_tar_archive, NULL },
{ "zip", write_zip_archive, parse_extra_zip_args },
};
static int run_remote_archiver(const char *remote, int argc,
const char **argv)
@@ -32,7 +15,7 @@ static int run_remote_archiver(const char *remote, int argc,
int fd[2], i, len, rv;
struct child_process *conn;
const char *exec = "git-upload-archive";
int exec_at = 0;
int exec_at = 0, exec_value_at = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -41,7 +24,14 @@ static int run_remote_archiver(const char *remote, int argc,
die("multiple --exec specified");
exec = arg + 7;
exec_at = i;
break;
} else if (!strcmp(arg, "--exec")) {
if (exec_at)
die("multiple --exec specified");
if (i + 1 >= argc)
die("option --exec requires a value");
exec = argv[i + 1];
exec_at = i;
exec_value_at = ++i;
}
}
@@ -49,7 +39,7 @@ static int run_remote_archiver(const char *remote, int argc,
conn = git_connect(fd, url, exec, 0);
for (i = 1; i < argc; i++) {
if (i == exec_at)
if (i == exec_at || i == exec_value_at)
continue;
packet_write(fd[1], "argument %s\n", argv[i]);
}
@@ -79,132 +69,6 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}
static int init_archiver(const char *name, struct archiver *ar)
{
int rv = -1, i;
for (i = 0; i < ARRAY_SIZE(archivers); i++) {
if (!strcmp(name, archivers[i].name)) {
memset(ar, 0, sizeof(*ar));
ar->name = archivers[i].name;
ar->write_archive = archivers[i].write_archive;
ar->parse_extra = archivers[i].parse_extra;
rv = 0;
break;
}
}
return rv;
}
void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args)
{
ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
}
void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,
const char *prefix)
{
const char *name = argv[0];
const unsigned char *commit_sha1;
time_t archive_time;
struct tree *tree;
const struct commit *commit;
unsigned char sha1[20];
if (get_sha1(name, sha1))
die("Not a valid object name");
commit = lookup_commit_reference_gently(sha1, 1);
if (commit) {
commit_sha1 = commit->object.sha1;
archive_time = commit->date;
} else {
commit_sha1 = NULL;
archive_time = time(NULL);
}
tree = parse_tree_indirect(sha1);
if (tree == NULL)
die("not a tree object");
if (prefix) {
unsigned char tree_sha1[20];
unsigned int mode;
int err;
err = get_tree_entry(tree->object.sha1, prefix,
tree_sha1, &mode);
if (err || !S_ISDIR(mode))
die("current working directory is untracked");
tree = parse_tree_indirect(tree_sha1);
}
ar_args->tree = tree;
ar_args->commit_sha1 = commit_sha1;
ar_args->commit = commit;
ar_args->time = archive_time;
}
int parse_archive_args(int argc, const char **argv, struct archiver *ar)
{
const char *extra_argv[MAX_EXTRA_ARGS];
int extra_argc = 0;
const char *format = "tar";
const char *base = "";
int verbose = 0;
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
for (i = 0; i < ARRAY_SIZE(archivers); i++)
printf("%s\n", archivers[i].name);
exit(0);
}
if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
verbose = 1;
continue;
}
if (!prefixcmp(arg, "--format=")) {
format = arg + 9;
continue;
}
if (!prefixcmp(arg, "--prefix=")) {
base = arg + 9;
continue;
}
if (!strcmp(arg, "--")) {
i++;
break;
}
if (arg[0] == '-') {
if (extra_argc > MAX_EXTRA_ARGS - 1)
die("Too many extra options");
extra_argv[extra_argc++] = arg;
continue;
}
break;
}
/* We need at least one parameter -- tree-ish */
if (argc - 1 < i)
usage(archive_usage);
if (init_archiver(format, ar) < 0)
die("Unknown archive format '%s'", format);
if (extra_argc) {
if (!ar->parse_extra)
die("'%s' format does not handle %s",
ar->name, extra_argv[0]);
ar->args.extra = ar->parse_extra(extra_argc, extra_argv);
}
ar->args.verbose = verbose;
ar->args.base = base;
return i;
}
static const char *extract_remote_arg(int *ac, const char **av)
{
int ix, iy, cnt = *ac;
@@ -221,6 +85,13 @@ static const char *extract_remote_arg(int *ac, const char **av)
die("Multiple --remote specified");
remote = arg + 9;
continue;
} else if (!strcmp(arg, "--remote")) {
if (remote)
die("Multiple --remote specified");
if (++ix >= cnt)
die("option --remote requires a value");
remote = av[ix];
continue;
}
if (arg[0] != '-')
no_more_options = 1;
@@ -238,8 +109,6 @@ static const char *extract_remote_arg(int *ac, const char **av)
int cmd_archive(int argc, const char **argv, const char *prefix)
{
struct archiver ar;
int tree_idx;
const char *remote = NULL;
remote = extract_remote_arg(&argc, argv);
@@ -248,14 +117,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
memset(&ar, 0, sizeof(ar));
tree_idx = parse_archive_args(argc, argv, &ar);
if (prefix == NULL)
prefix = setup_git_directory();
argv += tree_idx;
parse_treeish_arg(argv, &ar.args, prefix);
parse_pathspec_arg(argv + 1, &ar.args);
return ar.write_archive(&ar.args);
return write_archive(argc, argv, prefix, 1);
}

View File

@@ -16,11 +16,11 @@
#include "quote.h"
#include "xdiff-interface.h"
#include "cache-tree.h"
#include "path-list.h"
#include "string-list.h"
#include "mailmap.h"
#include "parse-options.h"
static char blame_usage[] = "git-blame [options] [rev-opts] [rev] [--] file";
static char blame_usage[] = "git blame [options] [rev-opts] [rev] [--] file";
static const char *blame_opt_usage[] = {
blame_usage,
@@ -40,7 +40,7 @@ static int blank_boundary;
static int incremental;
static int cmd_is_annotate;
static int xdl_opts = XDF_NEED_MINIMAL;
static struct path_list mailmap;
static struct string_list mailmap;
#ifndef DEBUG
#define DEBUG 0
@@ -153,6 +153,10 @@ struct blame_entry {
*/
char guilty;
/* true if the entry has been scanned for copies in the current parent
*/
char scanned;
/* the line number of the first line of this group in the
* suspect's file; internally all line numbers are 0 based.
*/
@@ -1008,7 +1012,8 @@ static int find_move_in_parent(struct scoreboard *sb,
while (made_progress) {
made_progress = 0;
for (e = sb->ent; e; e = e->next) {
if (e->guilty || !same_suspect(e->suspect, target))
if (e->guilty || !same_suspect(e->suspect, target) ||
ent_score(sb, e) < blame_move_score)
continue;
find_copy_in_blob(sb, e, parent, split, &file_p);
if (split[1].suspect &&
@@ -1033,6 +1038,7 @@ struct blame_list {
*/
static struct blame_list *setup_blame_list(struct scoreboard *sb,
struct origin *target,
int min_score,
int *num_ents_p)
{
struct blame_entry *e;
@@ -1040,18 +1046,32 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb,
struct blame_list *blame_list = NULL;
for (e = sb->ent, num_ents = 0; e; e = e->next)
if (!e->guilty && same_suspect(e->suspect, target))
if (!e->scanned && !e->guilty &&
same_suspect(e->suspect, target) &&
min_score < ent_score(sb, e))
num_ents++;
if (num_ents) {
blame_list = xcalloc(num_ents, sizeof(struct blame_list));
for (e = sb->ent, i = 0; e; e = e->next)
if (!e->guilty && same_suspect(e->suspect, target))
if (!e->scanned && !e->guilty &&
same_suspect(e->suspect, target) &&
min_score < ent_score(sb, e))
blame_list[i++].ent = e;
}
*num_ents_p = num_ents;
return blame_list;
}
/*
* Reset the scanned status on all entries.
*/
static void reset_scanned_flag(struct scoreboard *sb)
{
struct blame_entry *e;
for (e = sb->ent; e; e = e->next)
e->scanned = 0;
}
/*
* For lines target is suspected for, see if we can find code movement
* across file boundary from the parent commit. porigin is the path
@@ -1070,7 +1090,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
struct blame_list *blame_list;
int num_ents;
blame_list = setup_blame_list(sb, target, &num_ents);
blame_list = setup_blame_list(sb, target, blame_copy_score, &num_ents);
if (!blame_list)
return 1; /* nothing remains for this target */
@@ -1144,18 +1164,21 @@ static int find_copy_in_parent(struct scoreboard *sb,
split_blame(sb, split, blame_list[j].ent);
made_progress = 1;
}
else
blame_list[j].ent->scanned = 1;
decref_split(split);
}
free(blame_list);
if (!made_progress)
break;
blame_list = setup_blame_list(sb, target, &num_ents);
blame_list = setup_blame_list(sb, target, blame_copy_score, &num_ents);
if (!blame_list) {
retval = 1;
break;
}
}
reset_scanned_flag(sb);
diff_flush(&diff_opts);
diff_tree_release_paths(&diff_opts);
return retval;
@@ -1903,7 +1926,7 @@ static void sanity_check_refcnt(struct scoreboard *sb)
* Used for the command line parsing; check if the path exists
* in the working tree.
*/
static int has_path_in_work_tree(const char *path)
static int has_string_in_work_tree(const char *path)
{
struct stat st;
return !lstat(path, &st);
@@ -2367,14 +2390,14 @@ parse_done:
if (argc < 2)
usage_with_options(blame_opt_usage, options);
path = add_prefix(prefix, argv[argc - 1]);
if (argc == 3 && !has_path_in_work_tree(path)) { /* (2b) */
if (argc == 3 && !has_string_in_work_tree(path)) { /* (2b) */
path = add_prefix(prefix, argv[1]);
argv[1] = argv[2];
}
argv[argc - 1] = "--";
setup_work_tree();
if (!has_path_in_work_tree(path))
if (!has_string_in_work_tree(path))
die("cannot stat path %s: %s", path, strerror(errno));
}

View File

@@ -13,19 +13,19 @@
#include "remote.h"
#include "parse-options.h"
#include "branch.h"
#include "diff.h"
#include "revision.h"
static const char * const builtin_branch_usage[] = {
"git-branch [options] [-r | -a] [--merged | --no-merged]",
"git-branch [options] [-l] [-f] <branchname> [<start-point>]",
"git-branch [options] [-r] (-d | -D) <branchname>",
"git-branch [options] (-m | -M) [<oldbranch>] <newbranch>",
"git branch [options] [-r | -a] [--merged | --no-merged]",
"git branch [options] [-l] [-f] <branchname> [<start-point>]",
"git branch [options] [-r] (-d | -D) <branchname>",
"git branch [options] (-m | -M) [<oldbranch>] <newbranch>",
NULL
};
#define REF_UNKNOWN_TYPE 0x00
#define REF_LOCAL_BRANCH 0x01
#define REF_REMOTE_BRANCH 0x02
#define REF_TAG 0x04
static const char *head;
static unsigned char head_sha1[20];
@@ -181,25 +181,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
struct ref_item {
char *name;
unsigned int kind;
unsigned char sha1[20];
struct commit *commit;
};
struct ref_list {
struct rev_info revs;
int index, alloc, maxwidth;
struct ref_item *list;
struct commit_list *with_commit;
int kinds;
};
static int has_commit(const unsigned char *sha1, struct commit_list *with_commit)
static int has_commit(struct commit *commit, struct commit_list *with_commit)
{
struct commit *commit;
if (!with_commit)
return 1;
commit = lookup_commit_reference_gently(sha1, 1);
if (!commit)
return 0;
while (with_commit) {
struct commit *other;
@@ -215,7 +211,8 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
{
struct ref_list *ref_list = (struct ref_list*)(cb_data);
struct ref_item *newitem;
int kind = REF_UNKNOWN_TYPE;
struct commit *commit;
int kind;
int len;
static struct commit_list branch;
@@ -226,13 +223,15 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
} else if (!prefixcmp(refname, "refs/remotes/")) {
kind = REF_REMOTE_BRANCH;
refname += 13;
} else if (!prefixcmp(refname, "refs/tags/")) {
kind = REF_TAG;
refname += 10;
}
} else
return 0;
commit = lookup_commit_reference_gently(sha1, 1);
if (!commit)
return error("branch '%s' does not point at a commit", refname);
/* Filter with with_commit if specified */
if (!has_commit(sha1, ref_list->with_commit))
if (!has_commit(commit, ref_list->with_commit))
return 0;
/* Don't add types the caller doesn't want */
@@ -243,12 +242,8 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
branch.item = lookup_commit_reference_gently(sha1, 1);
if (!branch.item)
die("Unable to lookup tip of branch %s", refname);
if (merge_filter == SHOW_NOT_MERGED &&
has_commit(merge_filter_ref, &branch))
return 0;
if (merge_filter == SHOW_MERGED &&
!has_commit(merge_filter_ref, &branch))
return 0;
add_pending_object(&ref_list->revs,
(struct object *)branch.item, refname);
}
/* Resize buffer */
@@ -262,7 +257,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
newitem = &(ref_list->list[ref_list->index++]);
newitem->name = xstrdup(refname);
newitem->kind = kind;
hashcpy(newitem->sha1, sha1);
newitem->commit = commit;
len = strlen(newitem->name);
if (len > ref_list->maxwidth)
ref_list->maxwidth = len;
@@ -309,7 +304,13 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
{
char c;
int color;
struct commit *commit;
struct commit *commit = item->commit;
if (merge_filter != NO_FILTER) {
int is_merged = !!(item->commit->object.flags & UNINTERESTING);
if (is_merged != (merge_filter == SHOW_MERGED))
return;
}
switch (item->kind) {
case REF_LOCAL_BRANCH:
@@ -337,7 +338,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_init(&subject, 0);
stat[0] = '\0';
commit = lookup_commit(item->sha1);
commit = item->commit;
if (commit && !parse_commit(commit)) {
pretty_print_commit(CMIT_FMT_ONELINE, commit,
&subject, 0, NULL, NULL, 0, 0);
@@ -350,7 +351,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
printf("%c %s%-*s%s %s %s%s\n", c, branch_get_color(color),
maxwidth, item->name,
branch_get_color(COLOR_BRANCH_RESET),
find_unique_abbrev(item->sha1, abbrev),
find_unique_abbrev(item->commit->object.sha1, abbrev),
stat, sub);
strbuf_release(&subject);
} else {
@@ -363,22 +364,34 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
{
int i;
struct ref_list ref_list;
struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
memset(&ref_list, 0, sizeof(ref_list));
ref_list.kinds = kinds;
ref_list.with_commit = with_commit;
if (merge_filter != NO_FILTER)
init_revisions(&ref_list.revs, NULL);
for_each_ref(append_ref, &ref_list);
if (merge_filter != NO_FILTER) {
struct commit *filter;
filter = lookup_commit_reference_gently(merge_filter_ref, 0);
filter->object.flags |= UNINTERESTING;
add_pending_object(&ref_list.revs,
(struct object *) filter, "");
ref_list.revs.limited = 1;
prepare_revision_walk(&ref_list.revs);
}
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
detached = (detached && (kinds & REF_LOCAL_BRANCH));
if (detached && has_commit(head_sha1, with_commit)) {
if (detached && head_commit && has_commit(head_commit, with_commit)) {
struct ref_item item;
item.name = xstrdup("(no branch)");
item.kind = REF_LOCAL_BRANCH;
hashcpy(item.sha1, head_sha1);
item.commit = head_commit;
if (strlen(item.name) > ref_list.maxwidth)
ref_list.maxwidth = strlen(item.name);
ref_list.maxwidth = strlen(item.name);
print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
free(item.name);
}

View File

@@ -202,8 +202,8 @@ static int batch_objects(int print_contents)
}
static const char * const cat_file_usage[] = {
"git-cat-file [-t|-s|-e|-p|<type>] <sha1>",
"git-cat-file [--batch|--batch-check] < <list_of_sha1s>",
"git cat-file [-t|-s|-e|-p|<type>] <sha1>",
"git cat-file [--batch|--batch-check] < <list_of_sha1s>",
NULL
};

View File

@@ -4,7 +4,7 @@
#include "quote.h"
static const char check_attr_usage[] =
"git-check-attr attr... [--] pathname...";
"git check-attr attr... [--] pathname...";
int cmd_check_attr(int argc, const char **argv, const char *prefix)
{

View File

@@ -154,7 +154,7 @@ static void checkout_all(const char *prefix, int prefix_length)
}
static const char checkout_cache_usage[] =
"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]|all] [--prefix=<string>] [--temp] [--] <file>...";
"git checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]|all] [--prefix=<string>] [--temp] [--] <file>...";
static struct lock_file lock_file;

View File

@@ -43,7 +43,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
}
static int update_some(const unsigned char *sha1, const char *base, int baselen,
const char *pathname, unsigned mode, int stage)
const char *pathname, unsigned mode, int stage, void *context)
{
int len;
struct cache_entry *ce;
@@ -67,7 +67,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
static int read_tree_some(struct tree *tree, const char **pathspec)
{
read_tree_recursive(tree, "", 0, 0, pathspec, update_some);
read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
/* update the index with the given tree's info
* for all args, expanding wildcards, and exit
@@ -430,6 +430,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
OPT_END(),
};
int has_dash_dash;
memset(&opts, 0, sizeof(opts));
memset(&new, 0, sizeof(new));
@@ -438,12 +439,57 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.track = git_branch_track;
argc = parse_options(argc, argv, options, checkout_usage, 0);
argc = parse_options(argc, argv, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
if (!opts.new_branch && (opts.track != git_branch_track))
die("git checkout: --track and --no-track require -b");
if (opts.force && opts.merge)
die("git checkout: -f and -m are incompatible");
/*
* case 1: git checkout <ref> -- [<paths>]
*
* <ref> must be a valid tree, everything after the '--' must be
* a path.
*
* case 2: git checkout -- [<paths>]
*
* everything after the '--' must be paths.
*
* case 3: git checkout <something> [<paths>]
*
* With no paths, if <something> is a commit, that is to
* switch to the branch or detach HEAD at it.
*
* Otherwise <something> shall not be ambiguous.
* - If it's *only* a reference, treat it like case (1).
* - If it's only a path, treat it like case (2).
* - else: fail.
*
*/
if (argc) {
if (!strcmp(argv[0], "--")) { /* case (2) */
argv++;
argc--;
goto no_reference;
}
arg = argv[0];
if (get_sha1(arg, rev))
;
else if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
if (get_sha1(arg, rev)) {
if (has_dash_dash) /* case (1) */
die("invalid reference: %s", arg);
goto no_reference; /* case (3 -> 2) */
}
/* we can't end up being in (2) anymore, eat the argument */
argv++;
argc--;
if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
new.name = arg;
setup_branch_path(&new);
if (resolve_ref(new.path, rev, 1, NULL))
@@ -452,25 +498,28 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
new.path = NULL;
parse_commit(new.commit);
source_tree = new.commit->tree;
argv++;
argc--;
} else if ((source_tree = parse_tree_indirect(rev))) {
} else
source_tree = parse_tree_indirect(rev);
if (!source_tree) /* case (1): want a tree */
die("reference is not a tree: %s", arg);
if (!has_dash_dash) {/* case (3 -> 1) */
/*
* Do not complain the most common case
* git checkout branch
* even if there happen to be a file called 'branch';
* it would be extremely annoying.
*/
if (argc)
verify_non_filename(NULL, arg);
}
else {
argv++;
argc--;
}
}
if (argc && !strcmp(argv[0], "--")) {
argv++;
argc--;
}
if (!opts.new_branch && (opts.track != git_branch_track))
die("git checkout: --track and --no-track require -b");
if (opts.force && opts.merge)
die("git checkout: -f and -m are incompatible");
no_reference:
if (argc) {
const char **pathspec = get_pathspec(prefix, argv);

View File

@@ -15,7 +15,7 @@
static int force = -1; /* unset */
static const char *const builtin_clean_usage[] = {
"git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...",
"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...",
NULL
};

View File

@@ -29,7 +29,7 @@
*
*/
static const char * const builtin_clone_usage[] = {
"git-clone [options] [--] <repo> [<dir>]",
"git clone [options] [--] <repo> [<dir>]",
NULL
};
@@ -95,35 +95,38 @@ static char *get_repo_path(const char *repo, int *is_bundle)
static char *guess_dir_name(const char *repo, int is_bundle)
{
const char *p, *start, *end, *limit;
int after_slash_or_colon;
const char *end = repo + strlen(repo), *start;
/* Guess dir name from repository: strip trailing '/',
* strip trailing '[:/]*.{git,bundle}', strip leading '.*[/:]'. */
/*
* Strip trailing slashes and /.git
*/
while (repo < end && is_dir_sep(end[-1]))
end--;
if (end - repo > 5 && is_dir_sep(end[-5]) &&
!strncmp(end - 4, ".git", 4)) {
end -= 5;
while (repo < end && is_dir_sep(end[-1]))
end--;
}
after_slash_or_colon = 1;
limit = repo + strlen(repo);
start = repo;
end = limit;
for (p = repo; p < limit; p++) {
const char *prefix = is_bundle ? ".bundle" : ".git";
if (!prefixcmp(p, prefix)) {
if (!after_slash_or_colon)
end = p;
p += strlen(prefix) - 1;
} else if (!prefixcmp(p, ".bundle")) {
if (!after_slash_or_colon)
end = p;
p += 7;
} else if (is_dir_sep(*p) || *p == ':') {
if (end == limit)
end = p;
after_slash_or_colon = 1;
} else if (after_slash_or_colon) {
start = p;
end = limit;
after_slash_or_colon = 0;
}
/*
* Find last component, but be prepared that repo could have
* the form "remote.example.com:foo.git", i.e. no slash
* in the directory part.
*/
start = end;
while (repo < start && !is_dir_sep(start[-1]) && start[-1] != ':')
start--;
/*
* Strip .{bundle,git}.
*/
if (is_bundle) {
if (end - start > 7 && !strncmp(end - 7, ".bundle", 7))
end -= 7;
} else {
if (end - start > 4 && !strncmp(end - 4, ".git", 4))
end -= 4;
}
return xstrndup(start, end - start);
@@ -477,6 +480,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_quiet)
transport->verbose = -1;
if (option_upload_pack)
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
option_upload_pack);
refs = transport_get_remote_refs(transport);
transport_fetch_refs(transport, refs);
}

View File

@@ -21,17 +21,17 @@
#include "strbuf.h"
#include "utf8.h"
#include "parse-options.h"
#include "path-list.h"
#include "string-list.h"
#include "rerere.h"
#include "unpack-trees.h"
static const char * const builtin_commit_usage[] = {
"git-commit [options] [--] <filepattern>...",
"git commit [options] [--] <filepattern>...",
NULL
};
static const char * const builtin_status_usage[] = {
"git-status [options] [--] <filepattern>...",
"git status [options] [--] <filepattern>...",
NULL
};
@@ -68,8 +68,8 @@ static enum {
static char *cleanup_arg;
static int use_editor = 1, initial_commit, in_merge;
const char *only_include_assumed;
struct strbuf message;
static const char *only_include_assumed;
static struct strbuf message;
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
@@ -78,8 +78,7 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
strbuf_setlen(buf, 0);
else {
strbuf_addstr(buf, arg);
strbuf_addch(buf, '\n');
strbuf_addch(buf, '\n');
strbuf_addstr(buf, "\n\n");
}
return 0;
}
@@ -150,7 +149,7 @@ static int commit_index_files(void)
* Take a union of paths in the index and the named tree (typically, "HEAD"),
* and return the paths that match the given pattern in list.
*/
static int list_paths(struct path_list *list, const char *with_tree,
static int list_paths(struct string_list *list, const char *with_tree,
const char *prefix, const char **pattern)
{
int i;
@@ -169,24 +168,24 @@ static int list_paths(struct path_list *list, const char *with_tree,
continue;
if (!pathspec_match(pattern, m, ce->name, 0))
continue;
path_list_insert(ce->name, list);
string_list_insert(ce->name, list);
}
return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
}
static void add_remove_files(struct path_list *list)
static void add_remove_files(struct string_list *list)
{
int i;
for (i = 0; i < list->nr; i++) {
struct stat st;
struct path_list_item *p = &(list->items[i]);
struct string_list_item *p = &(list->items[i]);
if (!lstat(p->path, &st)) {
if (add_to_cache(p->path, &st, 0))
if (!lstat(p->string, &st)) {
if (add_to_cache(p->string, &st, 0))
die("updating files failed");
} else
remove_file_from_cache(p->path);
remove_file_from_cache(p->string);
}
}
@@ -221,7 +220,7 @@ static void create_base_index(void)
static char *prepare_index(int argc, const char **argv, const char *prefix)
{
int fd;
struct path_list partial;
struct string_list partial;
const char **pathspec = NULL;
if (interactive) {
@@ -305,7 +304,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
die("cannot do a partial commit during a merge.");
memset(&partial, 0, sizeof(partial));
partial.strdup_paths = 1;
partial.strdup_strings = 1;
if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
exit(1);
@@ -647,7 +646,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
char index[PATH_MAX];
const char *env[2] = { index, NULL };
snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
launch_editor(git_path(commit_editmsg), NULL, env);
if (launch_editor(git_path(commit_editmsg), NULL, env)) {
fprintf(stderr,
"Please supply the message using either -m or -F option.\n");
exit(1);
}
}
if (!no_verify &&
@@ -877,7 +880,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
}
}
int git_commit_config(const char *k, const char *v, void *cb)
static int git_commit_config(const char *k, const char *v, void *cb)
{
if (!strcmp(k, "commit.template"))
return git_config_string(&template_file, k, v);

View File

@@ -3,7 +3,7 @@
#include "color.h"
static const char git_config_set_usage[] =
"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
"git config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
static char *key;
static regex_t *key_regexp;
@@ -145,7 +145,7 @@ free_strings:
return ret;
}
char *normalize_value(const char *key, const char *value)
static char *normalize_value(const char *key, const char *value)
{
char *normalized;

View File

@@ -67,7 +67,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
}
static char const * const count_objects_usage[] = {
"git-count-objects [-v]",
"git count-objects [-v]",
NULL
};

View File

@@ -10,7 +10,7 @@
#define MAX_TAGS (FLAG_BITS - 1)
static const char * const describe_usage[] = {
"git-describe [options] <committish>*",
"git describe [options] <committish>*",
NULL
};
@@ -20,7 +20,7 @@ static int tags; /* But allow any tags if --tags is specified */
static int longformat;
static int abbrev = DEFAULT_ABBREV;
static int max_candidates = 10;
const char *pattern = NULL;
static const char *pattern;
static int always;
struct commit_name {

View File

@@ -10,7 +10,7 @@
#include "builtin.h"
static const char diff_files_usage[] =
"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
"git diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
COMMON_DIFF_OPTIONS_HELP;
int cmd_diff_files(int argc, const char **argv, const char *prefix)

View File

@@ -5,7 +5,7 @@
#include "builtin.h"
static const char diff_cache_usage[] =
"git-diff-index [-m] [--cached] "
"git diff-index [-m] [--cached] "
"[<common diff options>] <tree-ish> [<path>...]"
COMMON_DIFF_OPTIONS_HELP;

View File

@@ -53,7 +53,7 @@ static int diff_tree_stdin(char *line)
}
static const char diff_tree_usage[] =
"git-diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
"git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
"[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n"
" -r diff recursively\n"
" --root include the initial commit as diff against /dev/null\n"

View File

@@ -21,7 +21,7 @@ struct blobinfo {
};
static const char builtin_diff_usage[] =
"git-diff <options> <rev>{0,2} -- <path>*";
"git diff <options> <rev>{0,2} -- <path>*";
static void stuff_change(struct diff_options *opt,
unsigned old_mode, unsigned new_mode,
@@ -296,7 +296,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
* If the user asked for our exit code then don't start a
* pager or we would end up reporting its exit code instead.
*/
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS) &&
check_pager_config("diff") != 0)
setup_pager();
/*

View File

@@ -13,12 +13,12 @@
#include "log-tree.h"
#include "revision.h"
#include "decorate.h"
#include "path-list.h"
#include "string-list.h"
#include "utf8.h"
#include "parse-options.h"
static const char *fast_export_usage[] = {
"git-fast-export [rev-list-opts]",
"git fast-export [rev-list-opts]",
NULL
};
@@ -136,9 +136,18 @@ static void show_filemodify(struct diff_queue_struct *q,
if (is_null_sha1(spec->sha1))
printf("D %s\n", spec->path);
else {
struct object *object = lookup_object(spec->sha1);
printf("M %06o :%d %s\n", spec->mode,
get_object_mark(object), spec->path);
/*
* Links refer to objects in another repositories;
* output the SHA-1 verbatim.
*/
if (S_ISGITLINK(spec->mode))
printf("M %06o %s %s\n", spec->mode,
sha1_to_hex(spec->sha1), spec->path);
else {
struct object *object = lookup_object(spec->sha1);
printf("M %06o :%d %s\n", spec->mode,
get_object_mark(object), spec->path);
}
}
}
}
@@ -196,8 +205,10 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
diff_root_tree_sha1(commit->tree->object.sha1,
"", &rev->diffopt);
/* Export the referenced blobs, and remember the marks. */
for (i = 0; i < diff_queued_diff.nr; i++)
handle_object(diff_queued_diff.queue[i]->two->sha1);
if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
handle_object(diff_queued_diff.queue[i]->two->sha1);
mark_next_object(&commit->object);
if (!is_encoding_utf8(encoding))
@@ -298,7 +309,7 @@ static void handle_tag(const char *name, struct tag *tag)
}
static void get_tags_and_duplicates(struct object_array *pending,
struct path_list *extra_refs)
struct string_list *extra_refs)
{
struct tag *tag;
int i;
@@ -319,7 +330,7 @@ static void get_tags_and_duplicates(struct object_array *pending,
case OBJ_TAG:
tag = (struct tag *)e->item;
while (tag && tag->object.type == OBJ_TAG) {
path_list_insert(full_name, extra_refs)->util = tag;
string_list_insert(full_name, extra_refs)->util = tag;
tag = (struct tag *)tag->tagged;
}
if (!tag)
@@ -339,19 +350,19 @@ static void get_tags_and_duplicates(struct object_array *pending,
}
if (commit->util)
/* more than one name for the same object */
path_list_insert(full_name, extra_refs)->util = commit;
string_list_insert(full_name, extra_refs)->util = commit;
else
commit->util = full_name;
}
}
static void handle_tags_and_duplicates(struct path_list *extra_refs)
static void handle_tags_and_duplicates(struct string_list *extra_refs)
{
struct commit *commit;
int i;
for (i = extra_refs->nr - 1; i >= 0; i--) {
const char *name = extra_refs->items[i].path;
const char *name = extra_refs->items[i].string;
struct object *object = extra_refs->items[i].util;
switch (object->type) {
case OBJ_TAG:
@@ -434,7 +445,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
struct object_array commits = { 0, 0, NULL };
struct path_list extra_refs = { NULL, 0, 0, 0 };
struct string_list extra_refs = { NULL, 0, 0, 0 };
struct commit *commit;
char *export_filename = NULL, *import_filename = NULL;
struct option options[] = {

View File

@@ -18,7 +18,7 @@ static struct fetch_pack_args args = {
};
static const char fetch_pack_usage[] =
"git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
"git fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
#define COMPLETE (1U << 0)
#define COMMON (1U << 1)

View File

@@ -5,14 +5,14 @@
#include "refs.h"
#include "commit.h"
#include "builtin.h"
#include "path-list.h"
#include "string-list.h"
#include "remote.h"
#include "transport.h"
#include "run-command.h"
#include "parse-options.h"
static const char * const builtin_fetch_usage[] = {
"git-fetch [options] [<repository> <refspec>...]",
"git fetch [options] [<repository> <refspec>...]",
NULL
};
@@ -465,8 +465,8 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
static int add_existing(const char *refname, const unsigned char *sha1,
int flag, void *cbdata)
{
struct path_list *list = (struct path_list *)cbdata;
path_list_insert(refname, list);
struct string_list *list = (struct string_list *)cbdata;
string_list_insert(refname, list);
return 0;
}
@@ -485,8 +485,8 @@ static void find_non_local_tags(struct transport *transport,
struct ref **head,
struct ref ***tail)
{
struct path_list existing_refs = { NULL, 0, 0, 0 };
struct path_list new_refs = { NULL, 0, 0, 1 };
struct string_list existing_refs = { NULL, 0, 0, 0 };
struct string_list new_refs = { NULL, 0, 0, 1 };
char *ref_name;
int ref_name_len;
const unsigned char *ref_sha1;
@@ -515,11 +515,11 @@ static void find_non_local_tags(struct transport *transport,
}
}
if (!path_list_has_path(&existing_refs, ref_name) &&
!path_list_has_path(&new_refs, ref_name) &&
if (!string_list_has_string(&existing_refs, ref_name) &&
!string_list_has_string(&new_refs, ref_name) &&
(has_sha1_file(ref->old_sha1) ||
will_fetch(head, ref->old_sha1))) {
path_list_insert(ref_name, &new_refs);
string_list_insert(ref_name, &new_refs);
rm = alloc_ref_from_str(ref_name);
rm->peer_ref = alloc_ref_from_str(ref_name);
@@ -530,8 +530,8 @@ static void find_non_local_tags(struct transport *transport,
}
free(ref_name);
}
path_list_clear(&existing_refs, 0);
path_list_clear(&new_refs, 0);
string_list_clear(&existing_refs, 0);
string_list_clear(&new_refs, 0);
}
static int do_fetch(struct transport *transport,

View File

@@ -6,7 +6,7 @@
#include "tag.h"
static const char *fmt_merge_msg_usage =
"git-fmt-merge-msg [--log] [--no-log] [--file <file>]";
"git fmt-merge-msg [--log] [--no-log] [--file <file>]";
static int merge_summary;

View File

@@ -809,7 +809,7 @@ static struct ref_sort *default_sort(void)
return sort;
}
int opt_parse_sort(const struct option *opt, const char *arg, int unset)
static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
{
struct ref_sort **sort_tail = opt->value;
struct ref_sort *s;
@@ -831,7 +831,7 @@ int opt_parse_sort(const struct option *opt, const char *arg, int unset)
}
static char const * const for_each_ref_usage[] = {
"git-for-each-ref [options] [<pattern>]",
"git for-each-ref [options] [<pattern>]",
NULL
};

View File

@@ -377,6 +377,10 @@ static void fsck_dir(int i, char *path)
if (de->d_name[0] != '.')
break;
continue;
case 14:
if (prefixcmp(de->d_name, "tmp_obj_"))
break;
continue;
case 38:
sprintf(name, "%02x", i);
memcpy(name+2, de->d_name, len+1);
@@ -539,7 +543,7 @@ static int fsck_cache_tree(struct cache_tree *it)
}
static char const * const fsck_usage[] = {
"git-fsck [options] [<object>...]",
"git fsck [options] [<object>...]",
NULL
};

View File

@@ -18,7 +18,7 @@
#define FAILED_RUN "failed to run %s"
static const char * const builtin_gc_usage[] = {
"git-gc [options]",
"git gc [options]",
NULL
};

View File

@@ -427,33 +427,35 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
struct name_entry entry;
char *down;
int tn_len = strlen(tree_name);
char *path_buf = xmalloc(PATH_MAX + tn_len + 100);
struct strbuf pathbuf;
strbuf_init(&pathbuf, PATH_MAX + tn_len);
if (tn_len) {
tn_len = sprintf(path_buf, "%s:", tree_name);
down = path_buf + tn_len;
strcat(down, base);
strbuf_add(&pathbuf, tree_name, tn_len);
strbuf_addch(&pathbuf, ':');
tn_len = pathbuf.len;
}
else {
down = path_buf;
strcpy(down, base);
}
len = strlen(path_buf);
strbuf_addstr(&pathbuf, base);
len = pathbuf.len;
while (tree_entry(tree, &entry)) {
strcpy(path_buf + len, entry.path);
int te_len = tree_entry_len(entry.path, entry.sha1);
pathbuf.len = len;
strbuf_add(&pathbuf, entry.path, te_len);
if (S_ISDIR(entry.mode))
/* Match "abc/" against pathspec to
* decide if we want to descend into "abc"
* directory.
*/
strcpy(path_buf + len + tree_entry_len(entry.path, entry.sha1), "/");
strbuf_addch(&pathbuf, '/');
down = pathbuf.buf + tn_len;
if (!pathspec_matches(paths, down))
;
else if (S_ISREG(entry.mode))
hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len);
hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
else if (S_ISDIR(entry.mode)) {
enum object_type type;
struct tree_desc sub;
@@ -469,6 +471,7 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
free(data);
}
}
strbuf_release(&pathbuf);
return hit;
}
@@ -495,7 +498,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
}
static const char builtin_grep_usage[] =
"git-grep <option>* <rev>* [-e] <pattern> [<path>...]";
"git grep <option>* [-e] <pattern> <rev>* [[--] <path>...]";
static const char emsg_invalid_context_len[] =
"%s: invalid context length argument";

View File

@@ -354,7 +354,7 @@ static int guess_repository_type(const char *git_dir)
}
static const char init_db_usage[] =
"git-init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]";
"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]";
/*
* If you want to, you can share the DB area with any number of branches.

Some files were not shown because too many files have changed in this diff Show More