mirror of
https://github.com/git/git.git
synced 2026-03-13 18:33:25 +01:00
Merge with git://repo.or.cz/git.git#next.
This commit is contained in:
2
.mailmap
2
.mailmap
@@ -30,7 +30,9 @@ Robert Fitzsimons <robfitz@273k.net>
|
||||
Santi Béjar <sbejar@gmail.com>
|
||||
Sean Estabrooks <seanlkml@sympatico.ca>
|
||||
Shawn O. Pearce <spearce@spearce.org>
|
||||
Theodore Ts'o <tytso@mit.edu>
|
||||
Tony Luck <tony.luck@intel.com>
|
||||
Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
|
||||
Ville Skyttä <scop@xemacs.org>
|
||||
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
|
||||
anonymous <linux@horizon.com>
|
||||
|
||||
1
Documentation/.gitignore
vendored
1
Documentation/.gitignore
vendored
@@ -4,5 +4,4 @@
|
||||
*.7
|
||||
howto-index.txt
|
||||
doc.dep
|
||||
README
|
||||
cmds-*.txt
|
||||
|
||||
@@ -76,9 +76,12 @@ cmds_txt = cmds-ancillaryinterrogators.txt \
|
||||
cmds-mainporcelain.txt \
|
||||
cmds-plumbinginterrogators.txt \
|
||||
cmds-plumbingmanipulators.txt \
|
||||
cmds-synchingrepositories.txt
|
||||
cmds-synchingrepositories.txt \
|
||||
cmds-synchelpers.txt \
|
||||
cmds-purehelpers.txt \
|
||||
cmds-foreignscminterface.txt
|
||||
|
||||
$(cmds_txt): cmd-list.perl $(MAN1_TXT) $(MAN7_TXT)
|
||||
$(cmds_txt): cmd-list.perl $(MAN1_TXT)
|
||||
perl ./cmd-list.perl
|
||||
|
||||
git.7 git.html: git.txt core-intro.txt
|
||||
|
||||
@@ -45,7 +45,10 @@ for my $cat (qw(ancillaryinterrogators
|
||||
mainporcelain
|
||||
plumbinginterrogators
|
||||
plumbingmanipulators
|
||||
synchingrepositories)) {
|
||||
synchingrepositories
|
||||
foreignscminterface
|
||||
purehelpers
|
||||
synchelpers)) {
|
||||
my $out = "cmds-$cat.txt";
|
||||
open O, '>', "$out+" or die "Cannot open output file $out+";
|
||||
for (@{$cmds{$cat}}) {
|
||||
@@ -59,10 +62,10 @@ __DATA__
|
||||
git-add mainporcelain
|
||||
git-am mainporcelain
|
||||
git-annotate ancillaryinterrogators
|
||||
git-applymbox mainporcelain
|
||||
git-applypatch ancillarymanipulators
|
||||
git-applymbox ancillaryinterrogators
|
||||
git-applypatch purehelpers
|
||||
git-apply plumbingmanipulators
|
||||
git-archimport ancillarymanipulators
|
||||
git-archimport foreignscminterface
|
||||
git-archive mainporcelain
|
||||
git-bisect mainporcelain
|
||||
git-blame ancillaryinterrogators
|
||||
@@ -70,7 +73,7 @@ git-branch mainporcelain
|
||||
git-cat-file plumbinginterrogators
|
||||
git-checkout-index plumbingmanipulators
|
||||
git-checkout mainporcelain
|
||||
git-check-ref-format ancillaryinterrogators
|
||||
git-check-ref-format purehelpers
|
||||
git-cherry ancillaryinterrogators
|
||||
git-cherry-pick mainporcelain
|
||||
git-clean mainporcelain
|
||||
@@ -79,11 +82,11 @@ git-commit mainporcelain
|
||||
git-commit-tree plumbingmanipulators
|
||||
git-convert-objects ancillarymanipulators
|
||||
git-count-objects ancillaryinterrogators
|
||||
git-cvsexportcommit ancillarymanipulators
|
||||
git-cvsimport ancillarymanipulators
|
||||
git-cvsserver ancillarymanipulators
|
||||
git-daemon ancillaryinterrogators
|
||||
git-describe plumbinginterrogators
|
||||
git-cvsexportcommit foreignscminterface
|
||||
git-cvsimport foreignscminterface
|
||||
git-cvsserver foreignscminterface
|
||||
git-daemon synchingrepositories
|
||||
git-describe mainporcelain
|
||||
git-diff-files plumbinginterrogators
|
||||
git-diff-index plumbinginterrogators
|
||||
git-diff mainporcelain
|
||||
@@ -91,34 +94,34 @@ git-diff-stages plumbinginterrogators
|
||||
git-diff-tree plumbinginterrogators
|
||||
git-fetch mainporcelain
|
||||
git-fetch-pack synchingrepositories
|
||||
git-fmt-merge-msg ancillaryinterrogators
|
||||
git-fmt-merge-msg purehelpers
|
||||
git-for-each-ref plumbinginterrogators
|
||||
git-format-patch mainporcelain
|
||||
git-fsck-objects plumbinginterrogators
|
||||
git-gc ancillarymanipulators
|
||||
git-fsck-objects ancillaryinterrogators
|
||||
git-gc mainporcelain
|
||||
git-get-tar-commit-id ancillaryinterrogators
|
||||
git-grep mainporcelain
|
||||
git-hash-object plumbingmanipulators
|
||||
git-http-fetch synchingrepositories
|
||||
git-http-push synchingrepositories
|
||||
git-imap-send ancillaryinterrogators
|
||||
git-http-fetch synchelpers
|
||||
git-http-push synchelpers
|
||||
git-imap-send foreignscminterface
|
||||
git-index-pack plumbingmanipulators
|
||||
git-init plumbingmanipulators
|
||||
git-init mainporcelain
|
||||
git-instaweb ancillaryinterrogators
|
||||
gitk mainporcelain
|
||||
git-local-fetch synchingrepositories
|
||||
git-log mainporcelain
|
||||
git-lost-found ancillarymanipulators
|
||||
git-ls-files plumbinginterrogators
|
||||
git-ls-remote mainporcelain
|
||||
git-ls-remote plumbinginterrogators
|
||||
git-ls-tree plumbinginterrogators
|
||||
git-mailinfo ancillaryinterrogators
|
||||
git-mailsplit ancillaryinterrogators
|
||||
git-mailinfo purehelpers
|
||||
git-mailsplit purehelpers
|
||||
git-merge-base plumbinginterrogators
|
||||
git-merge-file plumbingmanipulators
|
||||
git-merge-index plumbingmanipulators
|
||||
git-merge mainporcelain
|
||||
git-merge-one-file ancillarymanipulators
|
||||
git-merge-one-file purehelpers
|
||||
git-merge-tree ancillaryinterrogators
|
||||
git-mktag plumbingmanipulators
|
||||
git-mktree plumbingmanipulators
|
||||
@@ -126,24 +129,24 @@ git-mv mainporcelain
|
||||
git-name-rev plumbinginterrogators
|
||||
git-pack-objects plumbingmanipulators
|
||||
git-pack-redundant plumbinginterrogators
|
||||
git-pack-refs mainporcelain
|
||||
git-parse-remote ancillaryinterrogators
|
||||
git-patch-id ancillaryinterrogators
|
||||
git-peek-remote synchingrepositories
|
||||
git-pack-refs ancillarymanipulators
|
||||
git-parse-remote synchelpers
|
||||
git-patch-id purehelpers
|
||||
git-peek-remote purehelpers
|
||||
git-prune ancillarymanipulators
|
||||
git-prune-packed plumbingmanipulators
|
||||
git-pull mainporcelain
|
||||
git-push mainporcelain
|
||||
git-quiltimport ancillarymanipulators
|
||||
git-quiltimport foreignscminterface
|
||||
git-read-tree plumbingmanipulators
|
||||
git-rebase mainporcelain
|
||||
git-receive-pack synchingrepositories
|
||||
git-receive-pack synchelpers
|
||||
git-reflog ancillarymanipulators
|
||||
git-relink ancillarymanipulators
|
||||
git-repack mainporcelain
|
||||
git-repo-config plumbingmanipulators
|
||||
git-request-pull ancillaryinterrogators
|
||||
git-rerere mainporcelain
|
||||
git-repack ancillarymanipulators
|
||||
git-repo-config ancillarymanipulators
|
||||
git-request-pull foreignscminterface
|
||||
git-rerere ancillaryinterrogators
|
||||
git-reset mainporcelain
|
||||
git-resolve mainporcelain
|
||||
git-revert mainporcelain
|
||||
@@ -151,34 +154,33 @@ git-rev-list plumbinginterrogators
|
||||
git-rev-parse ancillaryinterrogators
|
||||
git-rm mainporcelain
|
||||
git-runstatus ancillaryinterrogators
|
||||
git-send-email ancillaryinterrogators
|
||||
git-send-email foreignscminterface
|
||||
git-send-pack synchingrepositories
|
||||
git-shell synchingrepositories
|
||||
git-shell synchelpers
|
||||
git-shortlog mainporcelain
|
||||
git-show mainporcelain
|
||||
git-show-branch mainporcelain
|
||||
git-show-branch ancillaryinterrogators
|
||||
git-show-index plumbinginterrogators
|
||||
git-show-ref plumbinginterrogators
|
||||
git-sh-setup ancillarymanipulators
|
||||
git-sh-setup purehelpers
|
||||
git-ssh-fetch synchingrepositories
|
||||
git-ssh-upload synchingrepositories
|
||||
git-status mainporcelain
|
||||
git-stripspace ancillaryinterrogators
|
||||
git-svn ancillarymanipulators
|
||||
git-svnimport ancillarymanipulators
|
||||
git-symbolic-ref ancillaryinterrogators
|
||||
git-symbolic-ref ancillarymanipulators
|
||||
git-tag ancillarymanipulators
|
||||
git-stripspace purehelpers
|
||||
git-svn foreignscminterface
|
||||
git-svnimport foreignscminterface
|
||||
git-symbolic-ref plumbingmanipulators
|
||||
git-tag mainporcelain
|
||||
git-tar-tree plumbinginterrogators
|
||||
git-unpack-file plumbinginterrogators
|
||||
git-unpack-objects plumbingmanipulators
|
||||
git-update-index plumbingmanipulators
|
||||
git-update-ref ancillarymanipulators
|
||||
git-update-ref plumbingmanipulators
|
||||
git-update-server-info synchingrepositories
|
||||
git-upload-archive synchingrepositories
|
||||
git-upload-pack synchingrepositories
|
||||
git-upload-archive synchelpers
|
||||
git-upload-pack synchelpers
|
||||
git-var plumbinginterrogators
|
||||
git-verify-pack plumbinginterrogators
|
||||
git-verify-tag mainporcelain
|
||||
git-whatchanged mainporcelain
|
||||
git-verify-tag ancillaryinterrogators
|
||||
git-whatchanged ancillaryinterrogators
|
||||
git-write-tree plumbingmanipulators
|
||||
|
||||
@@ -14,14 +14,72 @@ dot-separated segment and the section name is everything before the last
|
||||
dot. The variable names are case-insensitive and only alphanumeric
|
||||
characters are allowed. Some variables may appear multiple times.
|
||||
|
||||
Syntax
|
||||
~~~~~~
|
||||
|
||||
The syntax is fairly flexible and permissive; whitespaces are mostly
|
||||
ignored. The '#' and ';' characters begin comments to the end of line,
|
||||
blank lines are ignored, lines containing strings enclosed in square
|
||||
brackets start sections and all the other lines are recognized
|
||||
as setting variables, in the form 'name = value'. If there is no equal
|
||||
sign on the line, the entire line is taken as 'name' and the variable
|
||||
is recognized as boolean "true". String values may be entirely or partially
|
||||
enclosed in double quotes; some variables may require special value format.
|
||||
ignored. The '#' and ';' characters begin comments to the end of line,
|
||||
blank lines are ignored.
|
||||
|
||||
The file consists of sections and variables. A section begins with
|
||||
the name of the section in square brackets and continues until the next
|
||||
section begins. Section names are not case sensitive. Only alphanumeric
|
||||
characters, '`-`' and '`.`' are allowed in section names. Each variable
|
||||
must belong to some section, which means that there must be section
|
||||
header before first setting of a variable.
|
||||
|
||||
Sections can be further divided into subsections. To begin a subsection
|
||||
put its name in double quotes, separated by space from the section name,
|
||||
in the section header, like in example below:
|
||||
|
||||
--------
|
||||
[section "subsection"]
|
||||
|
||||
--------
|
||||
|
||||
Subsection names can contain any characters except newline (doublequote
|
||||
'`"`' and backslash have to be escaped as '`\"`' and '`\\`',
|
||||
respecitvely) and are case sensitive. Section header cannot span multiple
|
||||
lines. Variables may belong directly to a section or to a given subsection.
|
||||
You can have `[section]` if you have `[section "subsection"]`, but you
|
||||
don't need to.
|
||||
|
||||
There is also (case insensitive) alternative `[section.subsection]` syntax.
|
||||
In this syntax subsection names follow the same restrictions as for section
|
||||
name.
|
||||
|
||||
All the other lines are recognized as setting variables, in the form
|
||||
'name = value'. If there is no equal sign on the line, the entire line
|
||||
is taken as 'name' and the variable is recognized as boolean "true".
|
||||
The variable names are case-insensitive and only alphanumeric
|
||||
characters and '`-`' are allowed. There can be more than one value
|
||||
for a given variable; we say then that variable is multivalued.
|
||||
|
||||
Leading and trailing whitespace in a variable value is discarded.
|
||||
Internal whitespace within a variable value is retained verbatim.
|
||||
|
||||
The values following the equals sign in variable assign are all either
|
||||
a string, an integer, or a boolean. Boolean values may be given as yes/no,
|
||||
0/1 or true/false. Case is not significant in boolean values, when
|
||||
converting value to the canonical form using '--bool' type specifier;
|
||||
`git-repo-config` will ensure that the output is "true" or "false".
|
||||
|
||||
String values may be entirely or partially enclosed in double quotes.
|
||||
You need to enclose variable value in double quotes if you want to
|
||||
preserve leading or trailing whitespace, or if variable value contains
|
||||
beginning of comment characters (if it contains '#' or ';').
|
||||
Double quote '`"`' and backslash '`\`' characters in variable value must
|
||||
be escaped: use '`\"`' for '`"`' and '`\\`' for '`\`'.
|
||||
|
||||
The following escape sequences (beside '`\"`' and '`\\`') are recognized:
|
||||
'`\n`' for newline character (NL), '`\t`' for horizontal tabulation (HT, TAB)
|
||||
and '`\b`' for backspace (BS). No other char escape sequence, nor octal
|
||||
char sequences are valid.
|
||||
|
||||
Variable value ending in a '`\`' is continued on the next line in the
|
||||
customary UNIX fashion.
|
||||
|
||||
Some variables may require special value format.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
@@ -40,6 +98,10 @@ Example
|
||||
remote = origin
|
||||
merge = refs/heads/devel
|
||||
|
||||
# Proxy settings
|
||||
[core]
|
||||
gitProxy="ssh" for "ssh://kernel.org/"
|
||||
gitProxy=default-proxy ; for the rest
|
||||
|
||||
Variables
|
||||
~~~~~~~~~
|
||||
@@ -233,6 +295,16 @@ diff.renames::
|
||||
will enable basic rename detection. If set to "copies" or
|
||||
"copy", it will detect copies, as well.
|
||||
|
||||
fetch.unpackLimit::
|
||||
If the number of objects fetched over the git native
|
||||
transfer is below this
|
||||
limit, then the objects will be unpacked into loose object
|
||||
files. However if the number of received objects equals or
|
||||
exceeds this limit then the received pack will be stored as
|
||||
a pack, after adding any missing delta bases. Storing the
|
||||
pack from a push can make the push operation complete faster,
|
||||
especially on slow filesystems.
|
||||
|
||||
format.headers::
|
||||
Additional email headers to include in a patch to be submitted
|
||||
by mail. See gitlink:git-format-patch[1].
|
||||
@@ -356,6 +428,10 @@ remote.<name>.push::
|
||||
The default set of "refspec" for gitlink:git-push[1]. See
|
||||
gitlink:git-push[1].
|
||||
|
||||
remote.<name>.receivepack::
|
||||
The default program to execute on the remote side when pulling. See
|
||||
option \--exec of gitlink:git-push[1].
|
||||
|
||||
repack.usedeltabaseoffset::
|
||||
Allow gitlink:git-repack[1] to create packs that uses
|
||||
delta-base offset. Defaults to false.
|
||||
@@ -412,3 +488,8 @@ receive.denyNonFastForwards::
|
||||
even if that push is forced. This configuration variable is
|
||||
set when initializing a shared repository.
|
||||
|
||||
transfer.unpackLimit::
|
||||
When `fetch.unpackLimit` or `receive.unpackLimit` are
|
||||
not set, the value of this variable is used instead.
|
||||
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ git-commit - Record changes to the repository
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-commit' [-a] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>]
|
||||
[--no-verify] [--amend] [-e] [--author <author>]
|
||||
'git-commit' [-a] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg> |
|
||||
--amend] [--no-verify] [-e] [--author <author>]
|
||||
[--] [[-i | -o ]<file>...]
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
@@ -131,14 +131,14 @@ Giving these options is an error when used with `--inetd`; use
|
||||
the facility of inet daemon to achieve the same before spawning
|
||||
`git-daemon` if needed.
|
||||
|
||||
--enable-service, --disable-service::
|
||||
--enable=service, --disable=service::
|
||||
Enable/disable the service site-wide per default. Note
|
||||
that a service disabled site-wide can still be enabled
|
||||
per repository if it is marked overridable and the
|
||||
repository enables the service with an configuration
|
||||
item.
|
||||
|
||||
--allow-override, --forbid-override::
|
||||
--allow-override=service, --forbid-override=service::
|
||||
Allow/forbid overriding the site-wide default with per
|
||||
repository configuration. By default, all the services
|
||||
are overridable.
|
||||
|
||||
@@ -8,7 +8,7 @@ git-fetch-pack - Receive missing objects from another repository
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-fetch-pack' [-q] [-k] [--exec=<git-upload-pack>] [<host>:]<directory> [<refs>...]
|
||||
'git-fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [-v] [<host>:]<directory> [<refs>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -28,17 +28,24 @@ have a common ancestor commit.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-q::
|
||||
\--all::
|
||||
Fetch all remote refs.
|
||||
|
||||
\--quiet, \-q::
|
||||
Pass '-q' flag to 'git-unpack-objects'; this makes the
|
||||
cloning process less verbose.
|
||||
|
||||
-k::
|
||||
\--keep, \-k::
|
||||
Do not invoke 'git-unpack-objects' on received data, but
|
||||
create a single packfile out of it instead, and store it
|
||||
in the object database. If provided twice then the pack is
|
||||
locked against repacking.
|
||||
|
||||
--exec=<git-upload-pack>::
|
||||
\--thin::
|
||||
Spend extra cycles to minimize the number of objects to be sent.
|
||||
Use it on slower connection.
|
||||
|
||||
\--upload-pack=<git-upload-pack>::
|
||||
Use this to specify the path to 'git-upload-pack' on the
|
||||
remote side, if is not found on your $PATH.
|
||||
Installations of sshd ignores the user's environment
|
||||
@@ -50,6 +57,15 @@ OPTIONS
|
||||
shells by having a lean .bashrc file (they set most of
|
||||
the things up in .bash_profile).
|
||||
|
||||
\--exec=<git-upload-pack>::
|
||||
Same as \--upload-pack=<git-upload-pack>.
|
||||
|
||||
\--depth=<n>::
|
||||
Limit fetching to ancestor-chains not longer than n.
|
||||
|
||||
\-v::
|
||||
Run verbosely.
|
||||
|
||||
<host>::
|
||||
A remote host that houses the repository. When this
|
||||
part is specified, 'git-upload-pack' is invoked via
|
||||
|
||||
@@ -8,7 +8,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-gc'
|
||||
'git-gc' [--prune]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -21,6 +21,21 @@ Users are encouraged to run this task on a regular basis within
|
||||
each repository to maintain good disk space utilization and good
|
||||
operating performance.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
--prune::
|
||||
Usually `git-gc` packs refs, expires old reflog entries,
|
||||
packs loose objects,
|
||||
and removes old 'rerere' records. Removal
|
||||
of unreferenced loose objects is an unsafe operation
|
||||
while other git operations are in progress, so it is not
|
||||
done by default. Pass this option if you want it, and only
|
||||
when you know nobody else is creating new objects in the
|
||||
repository at the same time (e.g. never use this option
|
||||
in a cron script).
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ git-peek-remote - List the references in a remote repository
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-peek-remote' [--exec=<git-upload-pack>] [<host>:]<directory>
|
||||
'git-peek-remote' [--upload-pack=<git-upload-pack>] [<host>:]<directory>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -17,7 +17,7 @@ stores them in the local repository under the same name.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--exec=<git-upload-pack>::
|
||||
\--upload-pack=<git-upload-pack>::
|
||||
Use this to specify the path to 'git-upload-pack' on the
|
||||
remote side, if it is not found on your $PATH. Some
|
||||
installations of sshd ignores the user's environment
|
||||
@@ -29,6 +29,9 @@ OPTIONS
|
||||
shells, but prefer having a lean .bashrc file (they set most of
|
||||
the things up in .bash_profile).
|
||||
|
||||
\--exec=<git-upload-pack>::
|
||||
Same \--upload-pack=<git-upload-pack>.
|
||||
|
||||
<host>::
|
||||
A remote host that houses the repository. When this
|
||||
part is specified, 'git-upload-pack' is invoked via
|
||||
|
||||
@@ -8,7 +8,7 @@ git-push - Update remote refs along with associated objects
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-push' [--all] [--tags] [--exec=<receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]
|
||||
'git-push' [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -67,12 +67,15 @@ the remote repository.
|
||||
addition to refspecs explicitly listed on the command
|
||||
line.
|
||||
|
||||
\--exec::
|
||||
\--receive-pack=<git-receive-pack>::
|
||||
Path to the 'git-receive-pack' program on the remote
|
||||
end. Sometimes useful when pushing to a remote
|
||||
repository over ssh, and you do not have the program in
|
||||
a directory on the default $PATH.
|
||||
|
||||
\--exec=<git-receive-pack>::
|
||||
Same as \--receive-pack=<git-receive-pack>.
|
||||
|
||||
-f, \--force::
|
||||
Usually, the command refuses to update a remote ref that is
|
||||
not a descendant of the local ref used to overwrite it.
|
||||
|
||||
@@ -27,6 +27,8 @@ SYNOPSIS
|
||||
[ \--pretty | \--header ]
|
||||
[ \--bisect ]
|
||||
[ \--merge ]
|
||||
[ \--reverse ]
|
||||
[ \--walk-reflogs ]
|
||||
<commit>... [ \-- <paths>... ]
|
||||
|
||||
DESCRIPTION
|
||||
@@ -190,6 +192,22 @@ limiting may be applied.
|
||||
In addition to the '<commit>' listed on the command
|
||||
line, read them from the standard input.
|
||||
|
||||
-g, --walk-reflogs::
|
||||
|
||||
Instead of walking the commit ancestry chain, walk
|
||||
reflog entries from the most recent one to older ones.
|
||||
When this option is used you cannot specify commits to
|
||||
exclude (that is, '{caret}commit', 'commit1..commit2',
|
||||
nor 'commit1...commit2' notations cannot be used).
|
||||
+
|
||||
With '\--pretty' format other than oneline (for obvious reasons),
|
||||
this causes the output to have two extra lines of information
|
||||
taken from the reflog. By default, 'commit@{Nth}' notation is
|
||||
used in the output. When the starting commit is specified as
|
||||
'commit@{now}', output also uses 'commit@{timestamp}' notation
|
||||
instead. Under '\--pretty=oneline', the commit message is
|
||||
prefixed with this information on the same line.
|
||||
|
||||
--merge::
|
||||
|
||||
After a failed merge, show refs that touch files having a
|
||||
@@ -249,6 +267,10 @@ By default, the commits are shown in reverse chronological order.
|
||||
parent comes before all of its children, but otherwise things
|
||||
are still ordered in the commit timestamp order.
|
||||
|
||||
--reverse::
|
||||
|
||||
Output the commits in reverse order.
|
||||
|
||||
Object Traversal
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ git-send-pack - Push objects over git protocol to another reposiotory
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-send-pack' [--all] [--force] [--exec=<git-receive-pack>] [<host>:]<directory> [<ref>...]
|
||||
'git-send-pack' [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -21,23 +21,33 @@ updates it from the current repository, sending named refs.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--exec=<git-receive-pack>::
|
||||
\--receive-pack=<git-receive-pack>::
|
||||
Path to the 'git-receive-pack' program on the remote
|
||||
end. Sometimes useful when pushing to a remote
|
||||
repository over ssh, and you do not have the program in
|
||||
a directory on the default $PATH.
|
||||
|
||||
--all::
|
||||
\--exec=<git-receive-pack>::
|
||||
Same as \--receive-pack=<git-receive-pack>.
|
||||
|
||||
\--all::
|
||||
Instead of explicitly specifying which refs to update,
|
||||
update all refs that locally exist.
|
||||
|
||||
--force::
|
||||
\--force::
|
||||
Usually, the command refuses to update a remote ref that
|
||||
is not an ancestor of the local ref used to overwrite it.
|
||||
This flag disables the check. What this means is that
|
||||
the remote repository can lose commits; use it with
|
||||
care.
|
||||
|
||||
\--verbose::
|
||||
Run verbosely.
|
||||
|
||||
\--thin::
|
||||
Spend extra cycles to minimize the number of objects to be sent.
|
||||
Use it on slower connection.
|
||||
|
||||
<host>::
|
||||
A remote host to house the repository. When this
|
||||
part is specified, 'git-receive-pack' is invoked via
|
||||
|
||||
@@ -11,7 +11,7 @@ SYNOPSIS
|
||||
'git-show-branch' [--all] [--remotes] [--topo-order] [--current]
|
||||
[--more=<n> | --list | --independent | --merge-base]
|
||||
[--no-name | --sha1-name] [--topics] [<rev> | <glob>]...
|
||||
'git-show-branch' --reflog[=<n>] <ref>
|
||||
'git-show-branch' (-g|--reflog)[=<n>[,<base>]] [--list] <ref>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -97,9 +97,11 @@ OPTIONS
|
||||
will show the revisions given by "git rev-list {caret}master
|
||||
topic1 topic2"
|
||||
|
||||
--reflog[=<n>] <ref>::
|
||||
Shows <n> most recent ref-log entries for the given ref.
|
||||
|
||||
--reflog[=<n>[,<base>]] <ref>::
|
||||
Shows <n> most recent ref-log entries for the given
|
||||
ref. If <base> is given, <n> entries going back from
|
||||
that entry. <base> can be specified as count or date.
|
||||
`-g` can be used as a short-hand for this option.
|
||||
|
||||
Note that --more, --list, --independent and --merge-base options
|
||||
are mutually exclusive.
|
||||
@@ -165,6 +167,13 @@ With this, `git show-branch` without extra parameters would show
|
||||
only the primary branches. In addition, if you happen to be on
|
||||
your topic branch, it is shown as well.
|
||||
|
||||
------------
|
||||
$ git show-branch --reflog='10,1 hour ago' --list master
|
||||
------------
|
||||
|
||||
shows 10 reflog entries going back from the tip as of 1 hour ago.
|
||||
Without `--list`, the output also shows how these tips are
|
||||
topologically related with each other.
|
||||
|
||||
|
||||
Author
|
||||
|
||||
@@ -3,14 +3,14 @@ git-tag(1)
|
||||
|
||||
NAME
|
||||
----
|
||||
git-tag - Create or verify a tag object signed with GPG
|
||||
git-tag - Create, list, delete or verify a tag object signed with GPG
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-tag' [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg> | -F <file>]
|
||||
<name> [<head>]
|
||||
'git-tag' [-a | -s | -u <key-id>] [-f | -v] [-m <msg> | -F <file>] <name> [<head>]
|
||||
'git-tag' -d <name>...
|
||||
'git-tag' -l [<pattern>]
|
||||
|
||||
DESCRIPTION
|
||||
@@ -55,7 +55,7 @@ OPTIONS
|
||||
Replace an existing tag with the given name (instead of failing)
|
||||
|
||||
-d::
|
||||
Delete an existing tag with the given name
|
||||
Delete existing tags with the given names.
|
||||
|
||||
-v::
|
||||
Verify the gpg signature of given the tag
|
||||
|
||||
@@ -93,6 +93,16 @@ Interrogators:
|
||||
|
||||
include::cmds-ancillaryinterrogators.txt[]
|
||||
|
||||
|
||||
Interacting with Others
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These commands are to interact with foreign SCM and with other
|
||||
people via patch over e-mail.
|
||||
|
||||
include::cmds-foreignscminterface.txt[]
|
||||
|
||||
|
||||
Low-level commands (plumbing)
|
||||
-----------------------------
|
||||
|
||||
@@ -102,11 +112,20 @@ development of alternative porcelains. Developers of such porcelains
|
||||
might start by reading about gitlink:git-update-index[1] and
|
||||
gitlink:git-read-tree[1].
|
||||
|
||||
We divide the low-level commands into commands that manipulate objects (in
|
||||
The interface (input, output, set of options and the semantics)
|
||||
to these low-level commands are meant to be a lot more stable
|
||||
than Porcelain level commands, because these commands are
|
||||
primarily for scripted use. The interface to Porcelain commands
|
||||
on the other hand are subject to change in order to improve the
|
||||
end user experience.
|
||||
|
||||
The following description divides
|
||||
the low-level commands into commands that manipulate objects (in
|
||||
the repository, index, and working tree), commands that interrogate and
|
||||
compare objects, and commands that move objects and references between
|
||||
repositories.
|
||||
|
||||
|
||||
Manipulation commands
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -127,6 +146,20 @@ Synching repositories
|
||||
|
||||
include::cmds-synchingrepositories.txt[]
|
||||
|
||||
The following are helper programs used by the above; end users
|
||||
typically do not use them directly.
|
||||
|
||||
include::cmds-synchelpers.txt[]
|
||||
|
||||
|
||||
Internal helper commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These are internal helper commands used by other commands; end
|
||||
users typically do not use them directly.
|
||||
|
||||
include::cmds-purehelpers.txt[]
|
||||
|
||||
|
||||
Configuration Mechanism
|
||||
-----------------------
|
||||
|
||||
@@ -343,8 +343,8 @@ And, as you can see with cat-file, this new entry refers to the
|
||||
current contents of the file:
|
||||
|
||||
------------------------------------------------
|
||||
$ git cat-file blob a6b11f7a
|
||||
goodbye, word
|
||||
$ git cat-file blob 8b9743b2
|
||||
goodbye, world
|
||||
------------------------------------------------
|
||||
|
||||
The "status" command is a useful way to get a quick summary of the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.5.0-rc1.GIT
|
||||
DEF_VER=v1.5.0-rc2.GIT
|
||||
|
||||
LF='
|
||||
'
|
||||
|
||||
4
Makefile
4
Makefile
@@ -240,7 +240,7 @@ LIB_H = \
|
||||
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
|
||||
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
|
||||
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
|
||||
spawn-pipe.h utf8.h
|
||||
spawn-pipe.h utf8.h reflog-walk.h
|
||||
|
||||
DIFF_OBJS = \
|
||||
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
|
||||
@@ -254,7 +254,7 @@ LIB_OBJS = \
|
||||
lockfile.o \
|
||||
spawn-pipe.o \
|
||||
object.o pack-check.o patch-delta.o path.o pkt-line.o sideband.o \
|
||||
reachable.o \
|
||||
reachable.o reflog-walk.o \
|
||||
quote.o read-cache.o refs.o run-command.o dir.o object-refs.o \
|
||||
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
|
||||
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
|
||||
|
||||
@@ -2589,7 +2589,7 @@ static int git_apply_config(const char *var, const char *value)
|
||||
}
|
||||
|
||||
|
||||
int cmd_apply(int argc, const char **argv, const char *prefix)
|
||||
int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
{
|
||||
int i;
|
||||
int read_stdin = 1;
|
||||
|
||||
@@ -74,6 +74,7 @@ static int run_remote_archiver(const char *remote, int argc,
|
||||
/* Now, start reading from fd[0] and spit it out to stdout */
|
||||
rv = recv_sideband("archive", fd[0], 1, 2);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
rv |= finish_connect(pid);
|
||||
|
||||
return !!rv;
|
||||
|
||||
@@ -324,7 +324,7 @@ static void create_branch(const char *name, const char *start_name,
|
||||
if (resolve_ref(ref, sha1, 1, NULL)) {
|
||||
if (!force)
|
||||
die("A branch named '%s' already exists.", name);
|
||||
else if (!strcmp(head, name))
|
||||
else if (!is_bare_repository() && !strcmp(head, name))
|
||||
die("Cannot force update the current branch.");
|
||||
}
|
||||
|
||||
|
||||
@@ -257,7 +257,9 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
||||
}
|
||||
else {
|
||||
git_config_set("core.bare", "false");
|
||||
git_config_set("core.logallrefupdates", "true");
|
||||
/* allow template config file to override the default */
|
||||
if (log_all_ref_updates == -1)
|
||||
git_config_set("core.logallrefupdates", "true");
|
||||
}
|
||||
return reinit;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,11 @@ static int cmd_log_walk(struct rev_info *rev)
|
||||
prepare_revision_walk(rev);
|
||||
while ((commit = get_revision(rev)) != NULL) {
|
||||
log_tree_commit(rev, commit);
|
||||
free(commit->buffer);
|
||||
commit->buffer = NULL;
|
||||
if (!rev->reflog_info) {
|
||||
/* we allow cycles in reflog ancestry */
|
||||
free(commit->buffer);
|
||||
commit->buffer = NULL;
|
||||
}
|
||||
free_commit_list(commit->parents);
|
||||
commit->parents = NULL;
|
||||
}
|
||||
@@ -473,7 +476,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
if (!rev.diffopt.text)
|
||||
rev.diffopt.binary = 1;
|
||||
|
||||
if (!output_directory)
|
||||
if (!output_directory && !use_stdout)
|
||||
output_directory = prefix;
|
||||
|
||||
if (output_directory) {
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
#define MAX_URI (16)
|
||||
|
||||
static const char push_usage[] = "git-push [--all] [--tags] [-f | --force] <repository> [<refspec>...]";
|
||||
static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
|
||||
|
||||
static int all, tags, force, thin = 1, verbose;
|
||||
static const char *execute;
|
||||
static const char *receivepack;
|
||||
|
||||
#define BUF_SIZE (2084)
|
||||
static char buffer[BUF_SIZE];
|
||||
@@ -143,6 +143,7 @@ static const char *config_repo;
|
||||
static int config_repo_len;
|
||||
static int config_current_uri;
|
||||
static int config_get_refspecs;
|
||||
static int config_get_receivepack;
|
||||
|
||||
static int get_remote_config(const char* key, const char* value)
|
||||
{
|
||||
@@ -157,6 +158,15 @@ static int get_remote_config(const char* key, const char* value)
|
||||
else if (config_get_refspecs &&
|
||||
!strcmp(key + 7 + config_repo_len, ".push"))
|
||||
add_refspec(xstrdup(value));
|
||||
else if (config_get_receivepack &&
|
||||
!strcmp(key + 7 + config_repo_len, ".receivepack")) {
|
||||
if (!receivepack) {
|
||||
char *rp = xmalloc(strlen(value) + 16);
|
||||
sprintf(rp, "--receive-pack=%s", value);
|
||||
receivepack = rp;
|
||||
} else
|
||||
error("more than one receivepack given, using the first");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -168,6 +178,7 @@ static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
|
||||
config_current_uri = 0;
|
||||
config_uri = uri;
|
||||
config_get_refspecs = !(refspec_nr || all || tags);
|
||||
config_get_receivepack = (receivepack == NULL);
|
||||
|
||||
git_config(get_remote_config);
|
||||
return config_current_uri;
|
||||
@@ -252,8 +263,8 @@ static int do_push(const char *repo)
|
||||
argv[argc++] = "--all";
|
||||
if (force)
|
||||
argv[argc++] = "--force";
|
||||
if (execute)
|
||||
argv[argc++] = execute;
|
||||
if (receivepack)
|
||||
argv[argc++] = receivepack;
|
||||
common_argc = argc;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -336,8 +347,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
||||
thin = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--receive-pack=", 15)) {
|
||||
receivepack = arg;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exec=", 7)) {
|
||||
execute = arg;
|
||||
receivepack = arg;
|
||||
continue;
|
||||
}
|
||||
usage(push_usage);
|
||||
|
||||
@@ -263,9 +263,6 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
|
||||
}
|
||||
|
||||
cb.ref_commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!cb.ref_commit)
|
||||
fprintf(stderr,
|
||||
"warning: ref '%s' does not point at a commit\n", ref);
|
||||
cb.ref = ref;
|
||||
cb.cmd = cmd;
|
||||
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "builtin.h"
|
||||
|
||||
static const char show_branch_usage[] =
|
||||
"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n] <branch>";
|
||||
"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
|
||||
static const char show_branch_usage_reflog[] =
|
||||
"--reflog is incompatible with --all, --remotes, --independent or --merge-base";
|
||||
|
||||
static int default_num;
|
||||
static int default_alloc;
|
||||
@@ -346,18 +348,21 @@ static void sort_ref_range(int bottom, int top)
|
||||
compare_ref_name);
|
||||
}
|
||||
|
||||
static int append_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
static int append_ref(const char *refname, const unsigned char *sha1,
|
||||
int allow_dups)
|
||||
{
|
||||
struct commit *commit = lookup_commit_reference_gently(sha1, 1);
|
||||
int i;
|
||||
|
||||
if (!commit)
|
||||
return 0;
|
||||
/* Avoid adding the same thing twice */
|
||||
for (i = 0; i < ref_name_cnt; i++)
|
||||
if (!strcmp(refname, ref_name[i]))
|
||||
return 0;
|
||||
|
||||
if (!allow_dups) {
|
||||
/* Avoid adding the same thing twice */
|
||||
for (i = 0; i < ref_name_cnt; i++)
|
||||
if (!strcmp(refname, ref_name[i]))
|
||||
return 0;
|
||||
}
|
||||
if (MAX_REVS <= ref_name_cnt) {
|
||||
fprintf(stderr, "warning: ignoring %s; "
|
||||
"cannot handle more than %d refs\n",
|
||||
@@ -380,7 +385,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f
|
||||
*/
|
||||
if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
|
||||
ofs = 5;
|
||||
return append_ref(refname + ofs, sha1, flag, cb_data);
|
||||
return append_ref(refname + ofs, sha1, 0);
|
||||
}
|
||||
|
||||
static int append_remote_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
@@ -394,14 +399,14 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
|
||||
*/
|
||||
if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
|
||||
ofs = 5;
|
||||
return append_ref(refname + ofs, sha1, flag, cb_data);
|
||||
return append_ref(refname + ofs, sha1, 0);
|
||||
}
|
||||
|
||||
static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
if (strncmp(refname, "refs/tags/", 10))
|
||||
return 0;
|
||||
return append_ref(refname + 5, sha1, flag, cb_data);
|
||||
return append_ref(refname + 5, sha1, 0);
|
||||
}
|
||||
|
||||
static const char *match_ref_pattern = NULL;
|
||||
@@ -434,7 +439,7 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
|
||||
return append_head_ref(refname, sha1, flag, cb_data);
|
||||
if (!strncmp("refs/tags/", refname, 10))
|
||||
return append_tag_ref(refname, sha1, flag, cb_data);
|
||||
return append_ref(refname, sha1, flag, cb_data);
|
||||
return append_ref(refname, sha1, 0);
|
||||
}
|
||||
|
||||
static void snarf_refs(int head, int remotes)
|
||||
@@ -507,7 +512,7 @@ static void append_one_rev(const char *av)
|
||||
{
|
||||
unsigned char revkey[20];
|
||||
if (!get_sha1(av, revkey)) {
|
||||
append_ref(av, revkey, 0, NULL);
|
||||
append_ref(av, revkey, 0);
|
||||
return;
|
||||
}
|
||||
if (strchr(av, '*') || strchr(av, '?') || strchr(av, '[')) {
|
||||
@@ -562,9 +567,24 @@ static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_reflog_param(const char *arg, int *cnt, const char **base)
|
||||
{
|
||||
char *ep;
|
||||
*cnt = strtoul(arg, &ep, 10);
|
||||
if (*ep == ',')
|
||||
*base = ep + 1;
|
||||
else if (*ep)
|
||||
die("unrecognized reflog param '%s'", arg + 9);
|
||||
else
|
||||
*base = NULL;
|
||||
if (*cnt <= 0)
|
||||
*cnt = DEFAULT_REFLOG;
|
||||
}
|
||||
|
||||
int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
{
|
||||
struct commit *rev[MAX_REVS], *commit;
|
||||
char *reflog_msg[MAX_REVS];
|
||||
struct commit_list *list = NULL, *seen = NULL;
|
||||
unsigned int rev_mask[MAX_REVS];
|
||||
int num_rev, i, extra = 0;
|
||||
@@ -585,6 +605,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
int topics = 0;
|
||||
int dense = 1;
|
||||
int reflog = 0;
|
||||
const char *reflog_base = NULL;
|
||||
|
||||
git_config(git_show_branch_config);
|
||||
|
||||
@@ -628,24 +649,34 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
dense = 0;
|
||||
else if (!strcmp(arg, "--date-order"))
|
||||
lifo = 0;
|
||||
else if (!strcmp(arg, "--reflog")) {
|
||||
else if (!strcmp(arg, "--reflog") || !strcmp(arg, "-g")) {
|
||||
reflog = DEFAULT_REFLOG;
|
||||
}
|
||||
else if (!strncmp(arg, "--reflog=", 9)) {
|
||||
char *end;
|
||||
reflog = strtoul(arg + 9, &end, 10);
|
||||
if (*end != '\0')
|
||||
die("unrecognized reflog count '%s'", arg + 9);
|
||||
}
|
||||
else if (!strncmp(arg, "--reflog=", 9))
|
||||
parse_reflog_param(arg + 9, &reflog, &reflog_base);
|
||||
else if (!strncmp(arg, "-g=", 3))
|
||||
parse_reflog_param(arg + 3, &reflog, &reflog_base);
|
||||
else
|
||||
usage(show_branch_usage);
|
||||
ac--; av++;
|
||||
}
|
||||
ac--; av++;
|
||||
|
||||
/* Only one of these is allowed */
|
||||
if (1 < independent + merge_base + (extra != 0) + (!!reflog))
|
||||
usage(show_branch_usage);
|
||||
if (!!extra || !!reflog) {
|
||||
/* "listing" mode is incompatible with
|
||||
* independent nor merge-base modes.
|
||||
*/
|
||||
if (independent || merge_base)
|
||||
usage(show_branch_usage);
|
||||
if (!!reflog && ((0 < extra) || all_heads || all_remotes))
|
||||
/*
|
||||
* Asking for --more in reflog mode does not
|
||||
* make sense. --list is Ok.
|
||||
*
|
||||
* Also --all and --remotes do not make sense either.
|
||||
*/
|
||||
usage(show_branch_usage_reflog);
|
||||
}
|
||||
|
||||
/* If nothing is specified, show all branches by default */
|
||||
if (ac + all_heads + all_remotes == 0)
|
||||
@@ -654,14 +685,54 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
if (all_heads + all_remotes)
|
||||
snarf_refs(all_heads, all_remotes);
|
||||
if (reflog) {
|
||||
int reflen;
|
||||
if (!ac)
|
||||
unsigned char sha1[20];
|
||||
char nth_desc[256];
|
||||
char *ref;
|
||||
int base = 0;
|
||||
if (ac != 1)
|
||||
die("--reflog option needs one branch name");
|
||||
reflen = strlen(*av);
|
||||
if (MAX_REVS < reflog)
|
||||
die("Only %d entries can be shown at one time.",
|
||||
MAX_REVS);
|
||||
if (!dwim_ref(*av, strlen(*av), sha1, &ref))
|
||||
die("No such ref %s", *av);
|
||||
|
||||
/* Has the base been specified? */
|
||||
if (reflog_base) {
|
||||
char *ep;
|
||||
base = strtoul(reflog_base, &ep, 10);
|
||||
if (*ep) {
|
||||
/* Ah, that is a date spec... */
|
||||
unsigned long at;
|
||||
at = approxidate(reflog_base);
|
||||
read_ref_at(ref, at, -1, sha1, NULL,
|
||||
NULL, NULL, &base);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < reflog; i++) {
|
||||
char *name = xmalloc(reflen + 20);
|
||||
sprintf(name, "%s@{%d}", *av, i);
|
||||
append_one_rev(name);
|
||||
char *logmsg, *msg, *m;
|
||||
unsigned long timestamp;
|
||||
int tz;
|
||||
|
||||
if (read_ref_at(ref, 0, base+i, sha1, &logmsg,
|
||||
×tamp, &tz, NULL)) {
|
||||
reflog = i;
|
||||
break;
|
||||
}
|
||||
msg = strchr(logmsg, '\t');
|
||||
if (!msg)
|
||||
msg = "(none)";
|
||||
else
|
||||
msg++;
|
||||
m = xmalloc(strlen(msg) + 200);
|
||||
sprintf(m, "(%s) %s",
|
||||
show_date(timestamp, tz, 1),
|
||||
msg);
|
||||
reflog_msg[i] = m;
|
||||
free(logmsg);
|
||||
sprintf(nth_desc, "%s@{%d}", *av, base+i);
|
||||
append_ref(nth_desc, sha1, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -760,8 +831,14 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
printf("%c [%s] ",
|
||||
is_head ? '*' : '!', ref_name[i]);
|
||||
}
|
||||
/* header lines never need name */
|
||||
show_one_commit(rev[i], 1);
|
||||
|
||||
if (!reflog) {
|
||||
/* header lines never need name */
|
||||
show_one_commit(rev[i], 1);
|
||||
}
|
||||
else
|
||||
puts(reflog_msg[i]);
|
||||
|
||||
if (is_head)
|
||||
head_at = i;
|
||||
}
|
||||
|
||||
3
cache.h
3
cache.h
@@ -129,6 +129,7 @@ extern int cache_errno;
|
||||
|
||||
extern int is_bare_repository_cfg;
|
||||
extern int is_bare_repository(void);
|
||||
extern int is_inside_git_dir(void);
|
||||
extern const char *get_git_dir(void);
|
||||
extern char *get_object_directory(void);
|
||||
extern char *get_refs_directory(void);
|
||||
@@ -300,6 +301,8 @@ extern int get_sha1_hex(const char *hex, unsigned char *sha1);
|
||||
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
||||
extern int read_ref(const char *filename, unsigned char *sha1);
|
||||
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
|
||||
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
|
||||
|
||||
extern int create_symref(const char *ref, const char *refs_heads_master);
|
||||
extern int validate_headref(const char *ref);
|
||||
|
||||
|
||||
2
commit.h
2
commit.h
@@ -110,7 +110,7 @@ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *r
|
||||
extern int register_shallow(const unsigned char *sha1);
|
||||
extern int unregister_shallow(const unsigned char *sha1);
|
||||
extern int write_shallow_commits(int fd, int use_pack_protocol);
|
||||
extern int is_repository_shallow();
|
||||
extern int is_repository_shallow(void);
|
||||
extern struct commit_list *get_shallow_commits(struct object_array *heads,
|
||||
int depth, int shallow_flag, int not_shallow_flag);
|
||||
|
||||
|
||||
5
config.c
5
config.c
@@ -661,6 +661,11 @@ int git_config_set_multivar(const char* key, const char* value,
|
||||
goto out_free;
|
||||
}
|
||||
c = tolower(c);
|
||||
} else if (c == '\n') {
|
||||
fprintf(stderr, "invalid key (newline): %s\n", key);
|
||||
free(store.key);
|
||||
ret = 1;
|
||||
goto out_free;
|
||||
}
|
||||
store.key[i] = c;
|
||||
}
|
||||
|
||||
@@ -530,7 +530,7 @@ static void git_tcp_connect(int fd[2], char *host)
|
||||
int sockfd = git_tcp_connect_sock(host);
|
||||
|
||||
fd[0] = sockfd;
|
||||
fd[1] = sockfd;
|
||||
fd[1] = dup(sockfd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
syn region gitLine start=/^#/ end=/$/
|
||||
syn region gitCommit start=/^# Added but not yet committed:$/ end=/^#$/ contains=gitHead,gitCommitFile
|
||||
syn region gitCommit start=/^# Changes to be committed:$/ end=/^#$/ contains=gitHead,gitCommitFile
|
||||
syn region gitHead contained start=/^# (.*)/ end=/^#$/
|
||||
syn region gitChanged start=/^# Changed but not added:/ end=/^#$/ contains=gitHead,gitChangedFile
|
||||
syn region gitChanged start=/^# Changed but not updated:/ end=/^#$/ contains=gitHead,gitChangedFile
|
||||
syn region gitUntracked start=/^# Untracked files:/ end=/^#$/ contains=gitHead,gitUntrackedFile
|
||||
|
||||
syn match gitCommitFile contained /^#\t.*/hs=s+2
|
||||
|
||||
5
date.c
5
date.c
@@ -62,12 +62,11 @@ const char *show_date(unsigned long time, int tz, int relative)
|
||||
|
||||
if (relative) {
|
||||
unsigned long diff;
|
||||
time_t t = gm_time_t(time, tz);
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if (now.tv_sec < t)
|
||||
if (now.tv_sec < time)
|
||||
return "in the future";
|
||||
diff = now.tv_sec - t;
|
||||
diff = now.tv_sec - time;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu seconds ago", diff);
|
||||
return timebuf;
|
||||
|
||||
118
fetch-pack.c
118
fetch-pack.c
@@ -4,16 +4,20 @@
|
||||
#include "commit.h"
|
||||
#include "tag.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "pack.h"
|
||||
#include "sideband.h"
|
||||
|
||||
static int keep_pack;
|
||||
static int transfer_unpack_limit = -1;
|
||||
static int fetch_unpack_limit = -1;
|
||||
static int unpack_limit = 100;
|
||||
static int quiet;
|
||||
static int verbose;
|
||||
static int fetch_all;
|
||||
static int depth;
|
||||
static const char fetch_pack_usage[] =
|
||||
"git-fetch-pack [--all] [-q] [-v] [-k] [--thin] [--exec=upload-pack] [--depth=<n>] [host:]directory <refs>...";
|
||||
static const char *exec = "git-upload-pack";
|
||||
"git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [-v] [<host>:]<directory> [<refs>...]";
|
||||
static const char *uploadpack = "git-upload-pack";
|
||||
|
||||
#define COMPLETE (1U << 0)
|
||||
#define COMMON (1U << 1)
|
||||
@@ -486,13 +490,58 @@ static pid_t setup_sideband(int fd[2], int xd[2])
|
||||
return side_pid;
|
||||
}
|
||||
|
||||
static int get_pack(int xd[2], const char **argv)
|
||||
static int get_pack(int xd[2])
|
||||
{
|
||||
int status;
|
||||
pid_t pid, side_pid;
|
||||
int fd[2];
|
||||
const char *argv[20];
|
||||
char keep_arg[256];
|
||||
char hdr_arg[256];
|
||||
const char **av;
|
||||
int do_keep = keep_pack;
|
||||
|
||||
side_pid = setup_sideband(fd, xd);
|
||||
|
||||
av = argv;
|
||||
*hdr_arg = 0;
|
||||
if (unpack_limit) {
|
||||
struct pack_header header;
|
||||
|
||||
if (read_pack_header(fd[0], &header))
|
||||
die("protocol error: bad pack header");
|
||||
snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
|
||||
ntohl(header.hdr_version), ntohl(header.hdr_entries));
|
||||
if (ntohl(header.hdr_entries) < unpack_limit)
|
||||
do_keep = 0;
|
||||
else
|
||||
do_keep = 1;
|
||||
}
|
||||
|
||||
if (do_keep) {
|
||||
*av++ = "index-pack";
|
||||
*av++ = "--stdin";
|
||||
if (!quiet)
|
||||
*av++ = "-v";
|
||||
if (use_thin_pack)
|
||||
*av++ = "--fix-thin";
|
||||
if (keep_pack > 1 || unpack_limit) {
|
||||
int s = sprintf(keep_arg,
|
||||
"--keep=fetch-pack %d on ", getpid());
|
||||
if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
|
||||
strcpy(keep_arg + s, "localhost");
|
||||
*av++ = keep_arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*av++ = "unpack-objects";
|
||||
if (quiet)
|
||||
*av++ = "-q";
|
||||
}
|
||||
if (*hdr_arg)
|
||||
*av++ = hdr_arg;
|
||||
*av++ = NULL;
|
||||
|
||||
pid = spawnv_git_cmd(argv, fd, NULL);
|
||||
if (pid < 0)
|
||||
die("fetch-pack: unable to fork off %s", argv[0]);
|
||||
@@ -514,39 +563,10 @@ static int get_pack(int xd[2], const char **argv)
|
||||
die("%s died of unnatural causes %d", argv[0], status);
|
||||
}
|
||||
|
||||
static int explode_rx_pack(int xd[2])
|
||||
{
|
||||
const char *argv[3] = { "unpack-objects", quiet ? "-q" : NULL, NULL };
|
||||
return get_pack(xd, argv);
|
||||
}
|
||||
|
||||
static int keep_rx_pack(int xd[2])
|
||||
{
|
||||
const char *argv[6];
|
||||
char keep_arg[256];
|
||||
int n = 0;
|
||||
|
||||
argv[n++] = "index-pack";
|
||||
argv[n++] = "--stdin";
|
||||
if (!quiet)
|
||||
argv[n++] = "-v";
|
||||
if (use_thin_pack)
|
||||
argv[n++] = "--fix-thin";
|
||||
if (keep_pack > 1) {
|
||||
int s = sprintf(keep_arg, "--keep=fetch-pack %i on ", getpid());
|
||||
if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
|
||||
strcpy(keep_arg + s, "localhost");
|
||||
argv[n++] = keep_arg;
|
||||
}
|
||||
argv[n] = NULL;
|
||||
return get_pack(xd, argv);
|
||||
}
|
||||
|
||||
static int fetch_pack(int fd[2], int nr_match, char **match)
|
||||
{
|
||||
struct ref *ref;
|
||||
unsigned char sha1[20];
|
||||
int status;
|
||||
|
||||
get_remote_heads(fd[0], &ref, 0, NULL, 0);
|
||||
if (is_repository_shallow() && !server_supports("shallow"))
|
||||
@@ -583,8 +603,7 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
|
||||
*/
|
||||
fprintf(stderr, "warning: no common commits\n");
|
||||
|
||||
status = (keep_pack) ? keep_rx_pack(fd) : explode_rx_pack(fd);
|
||||
if (status)
|
||||
if (get_pack(fd))
|
||||
die("git-fetch-pack: fetch failed.");
|
||||
|
||||
all_done:
|
||||
@@ -619,6 +638,21 @@ static int remove_duplicates(int nr_heads, char **heads)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static int fetch_pack_config(const char *var, const char *value)
|
||||
{
|
||||
if (strcmp(var, "fetch.unpacklimit") == 0) {
|
||||
fetch_unpack_limit = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(var, "transfer.unpacklimit") == 0) {
|
||||
transfer_unpack_limit = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
||||
static struct lock_file lock;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -630,6 +664,13 @@ int main(int argc, char **argv)
|
||||
struct stat st;
|
||||
|
||||
setup_git_directory();
|
||||
setup_ident();
|
||||
git_config(fetch_pack_config);
|
||||
|
||||
if (0 <= transfer_unpack_limit)
|
||||
unpack_limit = transfer_unpack_limit;
|
||||
else if (0 <= fetch_unpack_limit)
|
||||
unpack_limit = fetch_unpack_limit;
|
||||
|
||||
nr_heads = 0;
|
||||
heads = NULL;
|
||||
@@ -637,8 +678,12 @@ int main(int argc, char **argv)
|
||||
char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp("--upload-pack=", arg, 14)) {
|
||||
uploadpack = arg + 14;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
exec = arg + 7;
|
||||
uploadpack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
|
||||
@@ -647,6 +692,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
|
||||
keep_pack++;
|
||||
unpack_limit = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--thin", arg)) {
|
||||
@@ -676,7 +722,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if (!dest)
|
||||
usage(fetch_pack_usage);
|
||||
pid = git_connect(fd, dest, exec);
|
||||
pid = git_connect(fd, dest, uploadpack);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
if (heads && nr_heads)
|
||||
|
||||
133
fsck-objects.c
133
fsck-objects.c
@@ -54,6 +54,99 @@ static int objwarning(struct object *obj, const char *err, ...)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a single reachable object
|
||||
*/
|
||||
static void check_reachable_object(struct object *obj)
|
||||
{
|
||||
const struct object_refs *refs;
|
||||
|
||||
/*
|
||||
* We obviously want the object to be parsed,
|
||||
* except if it was in a pack-file and we didn't
|
||||
* do a full fsck
|
||||
*/
|
||||
if (!obj->parsed) {
|
||||
if (has_sha1_file(obj->sha1))
|
||||
return; /* it is in pack - forget about it */
|
||||
printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that everything that we try to reference is also good.
|
||||
*/
|
||||
refs = lookup_object_refs(obj);
|
||||
if (refs) {
|
||||
unsigned j;
|
||||
for (j = 0; j < refs->count; j++) {
|
||||
struct object *ref = refs->ref[j];
|
||||
if (ref->parsed ||
|
||||
(has_sha1_file(ref->sha1)))
|
||||
continue;
|
||||
printf("broken link from %7s %s\n",
|
||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
printf(" to %7s %s\n",
|
||||
typename(ref->type), sha1_to_hex(ref->sha1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a single unreachable object
|
||||
*/
|
||||
static void check_unreachable_object(struct object *obj)
|
||||
{
|
||||
/*
|
||||
* Missing unreachable object? Ignore it. It's not like
|
||||
* we miss it (since it can't be reached), nor do we want
|
||||
* to complain about it being unreachable (since it does
|
||||
* not exist).
|
||||
*/
|
||||
if (!obj->parsed)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Unreachable object that exists? Show it if asked to,
|
||||
* since this is something that is prunable.
|
||||
*/
|
||||
if (show_unreachable) {
|
||||
printf("unreachable %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* "!used" means that nothing at all points to it, including
|
||||
* other unreacahble objects. In other words, it's the "tip"
|
||||
* of some set of unreachable objects, usually a commit that
|
||||
* got dropped.
|
||||
*
|
||||
* Such starting points are more interesting than some random
|
||||
* set of unreachable objects, so we show them even if the user
|
||||
* hasn't asked for _all_ unreachable objects. If you have
|
||||
* deleted a branch by mistake, this is a prime candidate to
|
||||
* start looking at, for example.
|
||||
*/
|
||||
if (!obj->used) {
|
||||
printf("dangling %s %s\n", typename(obj->type),
|
||||
sha1_to_hex(obj->sha1));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise? It's there, it's unreachable, and some other unreachable
|
||||
* object points to it. Ignore it - it's not interesting, and we showed
|
||||
* all the interesting cases above.
|
||||
*/
|
||||
}
|
||||
|
||||
static void check_object(struct object *obj)
|
||||
{
|
||||
if (obj->flags & REACHABLE)
|
||||
check_reachable_object(obj);
|
||||
else
|
||||
check_unreachable_object(obj);
|
||||
}
|
||||
|
||||
static void check_connectivity(void)
|
||||
{
|
||||
@@ -62,46 +155,10 @@ static void check_connectivity(void)
|
||||
/* Look up all the requirements, warn about missing objects.. */
|
||||
max = get_max_object_index();
|
||||
for (i = 0; i < max; i++) {
|
||||
const struct object_refs *refs;
|
||||
struct object *obj = get_indexed_object(i);
|
||||
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
if (!obj->parsed) {
|
||||
if (has_sha1_file(obj->sha1))
|
||||
; /* it is in pack */
|
||||
else
|
||||
printf("missing %s %s\n",
|
||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
continue;
|
||||
}
|
||||
|
||||
refs = lookup_object_refs(obj);
|
||||
if (refs) {
|
||||
unsigned j;
|
||||
for (j = 0; j < refs->count; j++) {
|
||||
struct object *ref = refs->ref[j];
|
||||
if (ref->parsed ||
|
||||
(has_sha1_file(ref->sha1)))
|
||||
continue;
|
||||
printf("broken link from %7s %s\n",
|
||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
printf(" to %7s %s\n",
|
||||
typename(ref->type), sha1_to_hex(ref->sha1));
|
||||
}
|
||||
}
|
||||
|
||||
if (show_unreachable && !(obj->flags & REACHABLE)) {
|
||||
printf("unreachable %s %s\n",
|
||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!obj->used) {
|
||||
printf("dangling %s %s\n", typename(obj->type),
|
||||
sha1_to_hex(obj->sha1));
|
||||
}
|
||||
if (obj)
|
||||
check_object(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,17 +203,12 @@ else
|
||||
# Match the index to the working tree, and do a three-way.
|
||||
git diff-files --name-only | git update-index --remove --stdin &&
|
||||
work=`git write-tree` &&
|
||||
git read-tree --reset -u $new &&
|
||||
eval GITHEAD_$new=${new_name:-${branch:-$new}} GITHEAD_$work=local &&
|
||||
export GITHEAD_$new GITHEAD_$work &&
|
||||
git merge-recursive $old -- $new $work || exit
|
||||
git read-tree --reset -u $new || exit
|
||||
|
||||
if result=`git write-tree 2>/dev/null`
|
||||
then
|
||||
echo >&2 "Trivially automerged."
|
||||
else
|
||||
git merge-index -o git-merge-one-file -a
|
||||
fi
|
||||
eval GITHEAD_$new=${new_name:-${branch:-$new}} &&
|
||||
eval GITHEAD_$work=local &&
|
||||
export GITHEAD_$new GITHEAD_$work &&
|
||||
git merge-recursive $old -- $new $work
|
||||
|
||||
# Do not register the cleanly merged paths in the index yet.
|
||||
# this is not a real merge before committing, but just carrying
|
||||
|
||||
@@ -163,7 +163,9 @@ while
|
||||
1,-u|1,--upload-pack) usage ;;
|
||||
*,-u|*,--upload-pack)
|
||||
shift
|
||||
upload_pack="--exec=$1" ;;
|
||||
upload_pack="--upload-pack=$1" ;;
|
||||
*,--upload-pack=*)
|
||||
upload_pack=--upload-pack=$(expr "$1" : '-[^=]*=\(.*\)') ;;
|
||||
1,--depth) usage;;
|
||||
*,--depth)
|
||||
shift
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Copyright (c) 2005 Linus Torvalds
|
||||
# Copyright (c) 2006 Junio C Hamano
|
||||
|
||||
USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
|
||||
USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [[-i | -o] <path>...]'
|
||||
SUBDIRECTORY_OK=Yes
|
||||
. git-sh-setup
|
||||
require_work_tree
|
||||
@@ -284,9 +284,9 @@ esac
|
||||
|
||||
case "$log_given" in
|
||||
tt*)
|
||||
die "Only one of -c/-C/-F can be used." ;;
|
||||
die "Only one of -c/-C/-F/--amend can be used." ;;
|
||||
*tm*|*mt*)
|
||||
die "Option -m cannot be combined with -c/-C/-F." ;;
|
||||
die "Option -m cannot be combined with -c/-C/-F/--amend." ;;
|
||||
esac
|
||||
|
||||
case "$#,$also,$only,$amend" in
|
||||
@@ -462,15 +462,7 @@ if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
|
||||
fi >>"$GIT_DIR"/COMMIT_EDITMSG
|
||||
|
||||
# Author
|
||||
if test '' != "$force_author"
|
||||
then
|
||||
GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
|
||||
GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
|
||||
test '' != "$GIT_AUTHOR_NAME" &&
|
||||
test '' != "$GIT_AUTHOR_EMAIL" ||
|
||||
die "malformed --author parameter"
|
||||
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
|
||||
elif test '' != "$use_commit"
|
||||
if test '' != "$use_commit"
|
||||
then
|
||||
pick_author_script='
|
||||
/^author /{
|
||||
@@ -501,6 +493,15 @@ then
|
||||
export GIT_AUTHOR_EMAIL
|
||||
export GIT_AUTHOR_DATE
|
||||
fi
|
||||
if test '' != "$force_author"
|
||||
then
|
||||
GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
|
||||
GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
|
||||
test '' != "$GIT_AUTHOR_NAME" &&
|
||||
test '' != "$GIT_AUTHOR_EMAIL" ||
|
||||
die "malformed --author parameter"
|
||||
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
|
||||
fi
|
||||
|
||||
PARENTS="-p HEAD"
|
||||
if test -z "$initial_commit"
|
||||
|
||||
@@ -85,7 +85,7 @@ sub write_author_info($) {
|
||||
close ($f);
|
||||
}
|
||||
|
||||
getopts("hivmkuo:d:p:C:z:s:M:P:A:S:L:") or usage();
|
||||
getopts("haivmkuo:d:p:C:z:s:M:P:A:S:L:") or usage();
|
||||
usage if $opt_h;
|
||||
|
||||
@ARGV <= 1 or usage();
|
||||
|
||||
11
git-fetch.sh
11
git-fetch.sh
@@ -22,7 +22,6 @@ force=
|
||||
verbose=
|
||||
update_head_ok=
|
||||
exec=
|
||||
upload_pack=
|
||||
keep=
|
||||
shallow_depth=
|
||||
while case "$#" in 0) break ;; esac
|
||||
@@ -34,8 +33,12 @@ do
|
||||
--upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
|
||||
--upload-pa|--upload-pac|--upload-pack)
|
||||
shift
|
||||
exec="--exec=$1"
|
||||
upload_pack="-u $1"
|
||||
exec="--upload-pack=$1"
|
||||
;;
|
||||
--upl=*|--uplo=*|--uploa=*|--upload=*|\
|
||||
--upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
|
||||
exec=--upload-pack=$(expr "$1" : '-[^=]*=\(.*\)')
|
||||
shift
|
||||
;;
|
||||
-f|--f|--fo|--for|--forc|--force)
|
||||
force=t
|
||||
@@ -94,7 +97,7 @@ then
|
||||
fi
|
||||
|
||||
# Global that is reused later
|
||||
ls_remote_result=$(git ls-remote $upload_pack "$remote") ||
|
||||
ls_remote_result=$(git ls-remote $exec "$remote") ||
|
||||
die "Cannot get the repository state from $remote"
|
||||
|
||||
append_fetch_head () {
|
||||
|
||||
18
git-gc.sh
18
git-gc.sh
@@ -4,12 +4,26 @@
|
||||
#
|
||||
# Cleanup unreachable files and optimize the repository.
|
||||
|
||||
USAGE=''
|
||||
USAGE='git-gc [--prune]'
|
||||
SUBDIRECTORY_OK=Yes
|
||||
. git-sh-setup
|
||||
|
||||
no_prune=:
|
||||
while case $# in 0) break ;; esac
|
||||
do
|
||||
case "$1" in
|
||||
--prune)
|
||||
no_prune=
|
||||
;;
|
||||
--)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
git-pack-refs --prune &&
|
||||
git-reflog expire --all &&
|
||||
git-repack -a -d -l &&
|
||||
git-prune &&
|
||||
$no_prune git-prune &&
|
||||
git-rerere gc || exit
|
||||
|
||||
@@ -23,7 +23,11 @@ do
|
||||
-u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\
|
||||
--upload-pac|--upload-pack)
|
||||
shift
|
||||
exec="--exec=$1"
|
||||
exec="--upload-pack=$1"
|
||||
shift;;
|
||||
-u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\
|
||||
--upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
|
||||
exec=--upload-pack=$(expr "$1" : '-[^=]*=\(.*\)')
|
||||
shift;;
|
||||
--)
|
||||
shift; break ;;
|
||||
|
||||
@@ -275,8 +275,12 @@ case "$#" in
|
||||
git-checkout "$2" || usage
|
||||
;;
|
||||
*)
|
||||
branch_name=`git symbolic-ref HEAD` || die "No current branch"
|
||||
branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
|
||||
if branch_name=`git symbolic-ref -q HEAD`
|
||||
then
|
||||
branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
|
||||
else
|
||||
branch_name=HEAD ;# detached
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
branch=$(git-rev-parse --verify "${branch_name}^0") || exit
|
||||
|
||||
@@ -2856,7 +2856,7 @@ sub rmdirs {
|
||||
foreach my $d (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$rm) {
|
||||
$self->close_directory($bat->{$d}, $p);
|
||||
my ($dn) = ($d =~ m#^(.*?)/?(?:[^/]+)$#);
|
||||
print "\tD+\t/$d/\n" unless $q;
|
||||
print "\tD+\t$d/\n" unless $q;
|
||||
$self->SUPER::delete_entry($d, $r, $bat->{$dn}, $p);
|
||||
delete $bat->{$d};
|
||||
}
|
||||
|
||||
21
git-tag.sh
21
git-tag.sh
@@ -63,12 +63,21 @@ do
|
||||
;;
|
||||
-d)
|
||||
shift
|
||||
tag_name="$1"
|
||||
tag=$(git-show-ref --verify --hash -- "refs/tags/$tag_name") ||
|
||||
die "Seriously, what tag are you talking about?"
|
||||
git-update-ref -m 'tag: delete' -d "refs/tags/$tag_name" "$tag" &&
|
||||
echo "Deleted tag $tag_name."
|
||||
exit $?
|
||||
had_error=0
|
||||
for tag
|
||||
do
|
||||
cur=$(git-show-ref --verify --hash -- "refs/tags/$tag") || {
|
||||
echo >&2 "Seriously, what tag are you talking about?"
|
||||
had_error=1
|
||||
continue
|
||||
}
|
||||
git-update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || {
|
||||
had_error=1
|
||||
continue
|
||||
}
|
||||
echo "Deleted tag $tag."
|
||||
done
|
||||
exit $had_error
|
||||
;;
|
||||
-v)
|
||||
shift
|
||||
|
||||
2
git.c
2
git.c
@@ -218,7 +218,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||
int option;
|
||||
} commands[] = {
|
||||
{ "add", cmd_add, RUN_SETUP | NOT_BARE },
|
||||
{ "annotate", cmd_annotate, },
|
||||
{ "annotate", cmd_annotate, USE_PAGER },
|
||||
{ "apply", cmd_apply },
|
||||
{ "archive", cmd_archive },
|
||||
{ "blame", cmd_blame, RUN_SETUP | USE_PAGER },
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "diff.h"
|
||||
#include "commit.h"
|
||||
#include "log-tree.h"
|
||||
#include "reflog-walk.h"
|
||||
|
||||
static void show_parents(struct commit *commit, int abbrev)
|
||||
{
|
||||
@@ -223,6 +224,9 @@ void show_log(struct rev_info *opt, const char *sep)
|
||||
printf("%s",
|
||||
diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
|
||||
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
|
||||
if (opt->reflog_info)
|
||||
show_reflog_message(opt->reflog_info,
|
||||
opt->commit_format == CMIT_FMT_ONELINE);;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
5
pack.h
5
pack.h
@@ -44,4 +44,9 @@ struct pack_header {
|
||||
#define PACK_IDX_SIGNATURE 0xff744f63 /* "\377tOc" */
|
||||
|
||||
extern int verify_pack(struct packed_git *, int);
|
||||
|
||||
#define PH_ERROR_EOF (-1)
|
||||
#define PH_ERROR_PACK_SIGNATURE (-2)
|
||||
#define PH_ERROR_PROTOCOL (-3)
|
||||
extern int read_pack_header(int fd, struct pack_header *);
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "pkt-line.h"
|
||||
|
||||
static const char peek_remote_usage[] =
|
||||
"git-peek-remote [--exec=upload-pack] [host:]directory";
|
||||
static const char *exec = "git-upload-pack";
|
||||
"git-peek-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
|
||||
static const char *uploadpack = "git-upload-pack";
|
||||
|
||||
static int peek_remote(int fd[2], unsigned flags)
|
||||
{
|
||||
@@ -35,8 +35,12 @@ int main(int argc, char **argv)
|
||||
char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp("--upload-pack=", arg, 14)) {
|
||||
uploadpack = arg + 14;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
exec = arg + 7;
|
||||
uploadpack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--tags", arg)) {
|
||||
@@ -60,7 +64,7 @@ int main(int argc, char **argv)
|
||||
if (!dest || i != argc - 1)
|
||||
usage(peek_remote_usage);
|
||||
|
||||
pid = git_connect(fd, dest, exec);
|
||||
pid = git_connect(fd, dest, uploadpack);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
ret = peek_remote(fd, flags);
|
||||
|
||||
17
perl/Git.pm
17
perl/Git.pm
@@ -275,7 +275,7 @@ sub command {
|
||||
|
||||
} else {
|
||||
my @lines = <$fh>;
|
||||
chomp @lines;
|
||||
defined and chomp for @lines;
|
||||
try {
|
||||
_cmd_close($fh, $ctx);
|
||||
} catch Git::Error::Command with {
|
||||
@@ -736,13 +736,19 @@ sub _command_common_pipe {
|
||||
_check_valid_cmd($cmd);
|
||||
|
||||
my $fh;
|
||||
if ($^O eq '##INSERT_ACTIVESTATE_STRING_HERE##') {
|
||||
if ($^O eq 'MSWin32') {
|
||||
# ActiveState Perl
|
||||
#defined $opts{STDERR} and
|
||||
# warn 'ignoring STDERR option - running w/ ActiveState';
|
||||
$direction eq '-|' or
|
||||
die 'input pipe for ActiveState not implemented';
|
||||
tie ($fh, 'Git::activestate_pipe', $cmd, @args);
|
||||
# the strange construction with *ACPIPE is just to
|
||||
# explain the tie below that we want to bind to
|
||||
# a handle class, not scalar. It is not known if
|
||||
# it is something specific to ActiveState Perl or
|
||||
# just a Perl quirk.
|
||||
tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
|
||||
$fh = *ACPIPE;
|
||||
|
||||
} else {
|
||||
my $pid = open($fh, $direction);
|
||||
@@ -809,8 +815,9 @@ sub TIEHANDLE {
|
||||
# FIXME: This is probably horrible idea and the thing will explode
|
||||
# at the moment you give it arguments that require some quoting,
|
||||
# but I have no ActiveState clue... --pasky
|
||||
my $cmdline = join " ", @params;
|
||||
my @data = qx{$cmdline};
|
||||
# Let's just hope ActiveState Perl does at least the quoting
|
||||
# correctly.
|
||||
my @data = qx{git @params};
|
||||
bless { i => 0, data => \@data }, $class;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
|
||||
|
||||
static int deny_non_fast_forwards = 0;
|
||||
static int receive_unpack_limit = -1;
|
||||
static int transfer_unpack_limit = -1;
|
||||
static int unpack_limit = 100;
|
||||
static int report_status;
|
||||
|
||||
@@ -18,21 +20,22 @@ static int capabilities_sent;
|
||||
|
||||
static int receive_pack_config(const char *var, const char *value)
|
||||
{
|
||||
git_default_config(var, value);
|
||||
|
||||
if (strcmp(var, "receive.denynonfastforwards") == 0)
|
||||
{
|
||||
if (strcmp(var, "receive.denynonfastforwards") == 0) {
|
||||
deny_non_fast_forwards = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(var, "receive.unpacklimit") == 0)
|
||||
{
|
||||
unpack_limit = git_config_int(var, value);
|
||||
if (strcmp(var, "receive.unpacklimit") == 0) {
|
||||
receive_unpack_limit = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (strcmp(var, "transfer.unpacklimit") == 0) {
|
||||
transfer_unpack_limit = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
||||
static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
@@ -250,20 +253,22 @@ static void read_head_info(void)
|
||||
|
||||
static const char *parse_pack_header(struct pack_header *hdr)
|
||||
{
|
||||
char *c = (char*)hdr;
|
||||
ssize_t remaining = sizeof(struct pack_header);
|
||||
do {
|
||||
ssize_t r = xread(0, c, remaining);
|
||||
if (r <= 0)
|
||||
return "eof before pack header was fully read";
|
||||
remaining -= r;
|
||||
c += r;
|
||||
} while (remaining > 0);
|
||||
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
|
||||
switch (read_pack_header(0, hdr)) {
|
||||
case PH_ERROR_EOF:
|
||||
return "eof before pack header was fully read";
|
||||
|
||||
case PH_ERROR_PACK_SIGNATURE:
|
||||
return "protocol error (pack signature mismatch detected)";
|
||||
if (!pack_version_ok(hdr->hdr_version))
|
||||
|
||||
case PH_ERROR_PROTOCOL:
|
||||
return "protocol error (pack version unsupported)";
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
return "unknown error in parse_pack_header";
|
||||
|
||||
case 0:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *pack_lockfile;
|
||||
@@ -413,11 +418,19 @@ int main(int argc, char **argv)
|
||||
if(!enter_repo(dir, 0))
|
||||
die("'%s': unable to chdir or not a git archive", dir);
|
||||
|
||||
if (is_repository_shallow())
|
||||
die("attempt to push into a shallow repository");
|
||||
|
||||
setup_ident();
|
||||
/* don't die if gecos is empty */
|
||||
ignore_missing_committer_name();
|
||||
git_config(receive_pack_config);
|
||||
|
||||
if (0 <= transfer_unpack_limit)
|
||||
unpack_limit = transfer_unpack_limit;
|
||||
else if (0 <= receive_unpack_limit)
|
||||
unpack_limit = receive_unpack_limit;
|
||||
|
||||
write_head_info();
|
||||
|
||||
/* EOF */
|
||||
|
||||
250
reflog-walk.c
Normal file
250
reflog-walk.c
Normal file
@@ -0,0 +1,250 @@
|
||||
#include "cache.h"
|
||||
#include "commit.h"
|
||||
#include "refs.h"
|
||||
#include "diff.h"
|
||||
#include "revision.h"
|
||||
#include "path-list.h"
|
||||
#include "reflog-walk.h"
|
||||
|
||||
struct complete_reflogs {
|
||||
char *ref;
|
||||
struct reflog_info {
|
||||
unsigned char osha1[20], nsha1[20];
|
||||
char *email;
|
||||
unsigned long timestamp;
|
||||
int tz;
|
||||
char *message;
|
||||
} *items;
|
||||
int nr, alloc;
|
||||
};
|
||||
|
||||
static int read_one_reflog(unsigned char *osha1, unsigned char *nsha1,
|
||||
const char *email, unsigned long timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct complete_reflogs *array = cb_data;
|
||||
struct reflog_info *item;
|
||||
|
||||
if (array->nr >= array->alloc) {
|
||||
array->alloc = alloc_nr(array->nr + 1);
|
||||
array->items = xrealloc(array->items, array->alloc *
|
||||
sizeof(struct reflog_info));
|
||||
}
|
||||
item = array->items + array->nr;
|
||||
memcpy(item->osha1, osha1, 20);
|
||||
memcpy(item->nsha1, nsha1, 20);
|
||||
item->email = xstrdup(email);
|
||||
item->timestamp = timestamp;
|
||||
item->tz = tz;
|
||||
item->message = xstrdup(message);
|
||||
array->nr++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct complete_reflogs *read_complete_reflog(const char *ref)
|
||||
{
|
||||
struct complete_reflogs *reflogs =
|
||||
xcalloc(sizeof(struct complete_reflogs), 1);
|
||||
reflogs->ref = xstrdup(ref);
|
||||
for_each_reflog_ent(ref, read_one_reflog, reflogs);
|
||||
if (reflogs->nr == 0) {
|
||||
unsigned char sha1[20];
|
||||
const char *name = resolve_ref(ref, sha1, 1, NULL);
|
||||
if (name)
|
||||
for_each_reflog_ent(name, read_one_reflog, reflogs);
|
||||
}
|
||||
if (reflogs->nr == 0) {
|
||||
int len = strlen(ref);
|
||||
char *refname = xmalloc(len + 12);
|
||||
sprintf(refname, "refs/%s", ref);
|
||||
for_each_reflog_ent(refname, read_one_reflog, reflogs);
|
||||
if (reflogs->nr == 0) {
|
||||
sprintf(refname, "refs/heads/%s", ref);
|
||||
for_each_reflog_ent(refname, read_one_reflog, reflogs);
|
||||
}
|
||||
free(refname);
|
||||
}
|
||||
return reflogs;
|
||||
}
|
||||
|
||||
static int get_reflog_recno_by_time(struct complete_reflogs *array,
|
||||
unsigned long timestamp)
|
||||
{
|
||||
int i;
|
||||
for (i = array->nr - 1; i >= 0; i--)
|
||||
if (timestamp >= array->items[i].timestamp)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct commit_info_lifo {
|
||||
struct commit_info {
|
||||
struct commit *commit;
|
||||
void *util;
|
||||
} *items;
|
||||
int nr, alloc;
|
||||
};
|
||||
|
||||
static struct commit_info *get_commit_info(struct commit *commit,
|
||||
struct commit_info_lifo *lifo, int pop)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < lifo->nr; i++)
|
||||
if (lifo->items[i].commit == commit) {
|
||||
struct commit_info *result = &lifo->items[i];
|
||||
if (pop) {
|
||||
if (i + 1 < lifo->nr)
|
||||
memmove(lifo->items + i,
|
||||
lifo->items + i + 1,
|
||||
(lifo->nr - i) *
|
||||
sizeof(struct commit_info));
|
||||
lifo->nr--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void add_commit_info(struct commit *commit, void *util,
|
||||
struct commit_info_lifo *lifo)
|
||||
{
|
||||
struct commit_info *info;
|
||||
if (lifo->nr >= lifo->alloc) {
|
||||
lifo->alloc = alloc_nr(lifo->nr + 1);
|
||||
lifo->items = xrealloc(lifo->items,
|
||||
lifo->alloc * sizeof(struct commit_info));
|
||||
}
|
||||
info = lifo->items + lifo->nr;
|
||||
info->commit = commit;
|
||||
info->util = util;
|
||||
lifo->nr++;
|
||||
}
|
||||
|
||||
struct commit_reflog {
|
||||
int flag, recno;
|
||||
struct complete_reflogs *reflogs;
|
||||
};
|
||||
|
||||
struct reflog_walk_info {
|
||||
struct commit_info_lifo reflogs;
|
||||
struct path_list complete_reflogs;
|
||||
struct commit_reflog *last_commit_reflog;
|
||||
};
|
||||
|
||||
void init_reflog_walk(struct reflog_walk_info** info)
|
||||
{
|
||||
*info = xcalloc(sizeof(struct reflog_walk_info), 1);
|
||||
}
|
||||
|
||||
void add_reflog_for_walk(struct reflog_walk_info *info,
|
||||
struct commit *commit, const char *name)
|
||||
{
|
||||
unsigned long timestamp = 0;
|
||||
int recno = -1;
|
||||
struct path_list_item *item;
|
||||
struct complete_reflogs *reflogs;
|
||||
char *branch, *at = strchr(name, '@');
|
||||
struct commit_reflog *commit_reflog;
|
||||
|
||||
if (commit->object.flags & UNINTERESTING)
|
||||
die ("Cannot walk reflogs for %s", name);
|
||||
|
||||
branch = xstrdup(name);
|
||||
if (at && at[1] == '{') {
|
||||
char *ep;
|
||||
branch[at - name] = '\0';
|
||||
recno = strtoul(at + 2, &ep, 10);
|
||||
if (*ep != '}') {
|
||||
recno = -1;
|
||||
timestamp = approxidate(at + 2);
|
||||
}
|
||||
} else
|
||||
recno = 0;
|
||||
|
||||
item = path_list_lookup(branch, &info->complete_reflogs);
|
||||
if (item)
|
||||
reflogs = item->util;
|
||||
else {
|
||||
reflogs = read_complete_reflog(branch);
|
||||
if (!reflogs || reflogs->nr == 0)
|
||||
die("No reflogs found for '%s'", branch);
|
||||
path_list_insert(branch, &info->complete_reflogs)->util
|
||||
= reflogs;
|
||||
}
|
||||
|
||||
commit_reflog = xcalloc(sizeof(struct commit_reflog), 1);
|
||||
if (recno < 0) {
|
||||
commit_reflog->flag = 1;
|
||||
commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);
|
||||
if (commit_reflog->recno < 0) {
|
||||
free(branch);
|
||||
free(commit_reflog);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
commit_reflog->recno = reflogs->nr - recno - 1;
|
||||
commit_reflog->reflogs = reflogs;
|
||||
|
||||
add_commit_info(commit, commit_reflog, &info->reflogs);
|
||||
}
|
||||
|
||||
void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
|
||||
{
|
||||
struct commit_info *commit_info =
|
||||
get_commit_info(commit, &info->reflogs, 0);
|
||||
struct commit_reflog *commit_reflog;
|
||||
struct reflog_info *reflog;
|
||||
|
||||
info->last_commit_reflog = NULL;
|
||||
if (!commit_info)
|
||||
return;
|
||||
|
||||
commit_reflog = commit_info->util;
|
||||
if (commit_reflog->recno < 0) {
|
||||
commit->parents = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
|
||||
info->last_commit_reflog = commit_reflog;
|
||||
commit_reflog->recno--;
|
||||
commit_info->commit = (struct commit *)parse_object(reflog->osha1);
|
||||
if (!commit_info->commit) {
|
||||
commit->parents = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
commit->parents = xcalloc(sizeof(struct commit_list), 1);
|
||||
commit->parents->item = commit_info->commit;
|
||||
commit->object.flags &= ~(ADDED | SEEN | SHOWN);
|
||||
}
|
||||
|
||||
void show_reflog_message(struct reflog_walk_info* info, int oneline)
|
||||
{
|
||||
if (info && info->last_commit_reflog) {
|
||||
struct commit_reflog *commit_reflog = info->last_commit_reflog;
|
||||
struct reflog_info *info;
|
||||
|
||||
info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
|
||||
if (oneline) {
|
||||
printf("%s@{", commit_reflog->reflogs->ref);
|
||||
if (commit_reflog->flag)
|
||||
printf("%s", show_date(info->timestamp, 0, 1));
|
||||
else
|
||||
printf("%d", commit_reflog->reflogs->nr
|
||||
- 2 - commit_reflog->recno);
|
||||
printf("}: ");
|
||||
}
|
||||
else {
|
||||
printf("Reflog: %s@{", commit_reflog->reflogs->ref);
|
||||
if (commit_reflog->flag)
|
||||
printf("%s", show_rfc2822_date(info->timestamp,
|
||||
info->tz));
|
||||
else
|
||||
printf("%d", commit_reflog->reflogs->nr
|
||||
- 2 - commit_reflog->recno);
|
||||
printf("} (%s)\nReflog message: %s",
|
||||
info->email, info->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
reflog-walk.h
Normal file
11
reflog-walk.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef REFLOG_WALK_H
|
||||
#define REFLOG_WALK_H
|
||||
|
||||
extern void init_reflog_walk(struct reflog_walk_info** info);
|
||||
extern void add_reflog_for_walk(struct reflog_walk_info *info,
|
||||
struct commit *commit, const char *name);
|
||||
extern void fake_reflog_parent(struct reflog_walk_info *info,
|
||||
struct commit *commit);
|
||||
extern void show_reflog_message(struct reflog_walk_info *info, int);
|
||||
|
||||
#endif
|
||||
59
refs.c
59
refs.c
@@ -1036,7 +1036,21 @@ int write_ref_sha1(struct ref_lock *lock,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1)
|
||||
static char *ref_msg(const char *line, const char *endp)
|
||||
{
|
||||
const char *ep;
|
||||
char *msg;
|
||||
|
||||
line += 82;
|
||||
for (ep = line; ep < endp && *ep != '\n'; ep++)
|
||||
;
|
||||
msg = xmalloc(ep - line + 1);
|
||||
memcpy(msg, line, ep - line);
|
||||
msg[ep - line] = 0;
|
||||
return msg;
|
||||
}
|
||||
|
||||
int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
|
||||
{
|
||||
const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
|
||||
char *tz_c;
|
||||
@@ -1044,6 +1058,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
struct stat st;
|
||||
unsigned long date;
|
||||
unsigned char logged_sha1[20];
|
||||
void *log_mapped;
|
||||
|
||||
logfile = git_path("logs/%s", ref);
|
||||
logfd = open(logfile, O_RDONLY, 0);
|
||||
@@ -1052,7 +1067,8 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
fstat(logfd, &st);
|
||||
if (!st.st_size)
|
||||
die("Log %s is empty.", logfile);
|
||||
logdata = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
|
||||
log_mapped = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
|
||||
logdata = log_mapped;
|
||||
close(logfd);
|
||||
|
||||
lastrec = NULL;
|
||||
@@ -1071,13 +1087,21 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
die("Log %s is corrupt.", logfile);
|
||||
date = strtoul(lastgt + 1, &tz_c, 10);
|
||||
if (date <= at_time || cnt == 0) {
|
||||
tz = strtoul(tz_c, NULL, 10);
|
||||
if (msg)
|
||||
*msg = ref_msg(rec, logend);
|
||||
if (cutoff_time)
|
||||
*cutoff_time = date;
|
||||
if (cutoff_tz)
|
||||
*cutoff_tz = tz;
|
||||
if (cutoff_cnt)
|
||||
*cutoff_cnt = reccnt - 1;
|
||||
if (lastrec) {
|
||||
if (get_sha1_hex(lastrec, logged_sha1))
|
||||
die("Log %s is corrupt.", logfile);
|
||||
if (get_sha1_hex(rec + 41, sha1))
|
||||
die("Log %s is corrupt.", logfile);
|
||||
if (hashcmp(logged_sha1, sha1)) {
|
||||
tz = strtoul(tz_c, NULL, 10);
|
||||
fprintf(stderr,
|
||||
"warning: Log %s has gap after %s.\n",
|
||||
logfile, show_rfc2822_date(date, tz));
|
||||
@@ -1091,13 +1115,12 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
if (get_sha1_hex(rec + 41, logged_sha1))
|
||||
die("Log %s is corrupt.", logfile);
|
||||
if (hashcmp(logged_sha1, sha1)) {
|
||||
tz = strtoul(tz_c, NULL, 10);
|
||||
fprintf(stderr,
|
||||
"warning: Log %s unexpectedly ended on %s.\n",
|
||||
logfile, show_rfc2822_date(date, tz));
|
||||
}
|
||||
}
|
||||
munmap((void*)logdata, st.st_size);
|
||||
munmap(log_mapped, st.st_size);
|
||||
return 0;
|
||||
}
|
||||
lastrec = rec;
|
||||
@@ -1114,14 +1137,17 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
tz = strtoul(tz_c, NULL, 10);
|
||||
if (get_sha1_hex(logdata, sha1))
|
||||
die("Log %s is corrupt.", logfile);
|
||||
munmap((void*)logdata, st.st_size);
|
||||
if (at_time)
|
||||
fprintf(stderr, "warning: Log %s only goes back to %s.\n",
|
||||
logfile, show_rfc2822_date(date, tz));
|
||||
else
|
||||
fprintf(stderr, "warning: Log %s only has %d entries.\n",
|
||||
logfile, reccnt);
|
||||
return 0;
|
||||
if (msg)
|
||||
*msg = ref_msg(logdata, logend);
|
||||
munmap(log_mapped, st.st_size);
|
||||
|
||||
if (cutoff_time)
|
||||
*cutoff_time = date;
|
||||
if (cutoff_tz)
|
||||
*cutoff_tz = tz;
|
||||
if (cutoff_cnt)
|
||||
*cutoff_cnt = reccnt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
@@ -1129,6 +1155,7 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
const char *logfile;
|
||||
FILE *logfp;
|
||||
char buf[1024];
|
||||
int ret = 0;
|
||||
|
||||
logfile = git_path("logs/%s", ref);
|
||||
logfp = fopen(logfile, "r");
|
||||
@@ -1138,7 +1165,7 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
unsigned char osha1[20], nsha1[20];
|
||||
char *email_end, *message;
|
||||
unsigned long timestamp;
|
||||
int len, ret, tz;
|
||||
int len, tz;
|
||||
|
||||
/* old SP new SP name <email> SP time TAB msg LF */
|
||||
len = strlen(buf);
|
||||
@@ -1159,9 +1186,9 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
message += 7;
|
||||
ret = fn(osha1, nsha1, buf+82, timestamp, tz, message, cb_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
fclose(logfp);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
2
refs.h
2
refs.h
@@ -42,7 +42,7 @@ extern void unlock_ref(struct ref_lock *lock);
|
||||
extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);
|
||||
|
||||
/** Reads log for the value of ref during at_time. **/
|
||||
extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1);
|
||||
extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
|
||||
|
||||
/* iterate over reflog entries */
|
||||
typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
|
||||
|
||||
50
revision.c
50
revision.c
@@ -7,6 +7,7 @@
|
||||
#include "refs.h"
|
||||
#include "revision.h"
|
||||
#include "grep.h"
|
||||
#include "reflog-walk.h"
|
||||
|
||||
static char *path_name(struct name_path *path, const char *name)
|
||||
{
|
||||
@@ -116,6 +117,9 @@ void mark_parents_uninteresting(struct commit *commit)
|
||||
void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
|
||||
{
|
||||
add_object_array(obj, name, &revs->pending);
|
||||
if (revs->reflog_info && obj->type == OBJ_COMMIT)
|
||||
add_reflog_for_walk(revs->reflog_info,
|
||||
(struct commit *)obj, name);
|
||||
}
|
||||
|
||||
static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
|
||||
@@ -864,6 +868,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
handle_reflog(revs, flags);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-g") ||
|
||||
!strcmp(arg, "--walk-reflogs")) {
|
||||
init_reflog_walk(&revs->reflog_info);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--not")) {
|
||||
flags ^= UNINTERESTING;
|
||||
continue;
|
||||
@@ -1049,6 +1058,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
git_log_output_encoding = "";
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--reverse")) {
|
||||
revs->reverse ^= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
|
||||
if (opts > 0) {
|
||||
@@ -1210,6 +1223,9 @@ static struct commit *get_revision_1(struct rev_info *revs)
|
||||
revs->commits = entry->next;
|
||||
free(entry);
|
||||
|
||||
if (revs->reflog_info)
|
||||
fake_reflog_parent(revs->reflog_info, commit);
|
||||
|
||||
/*
|
||||
* If we haven't done the list limiting, we need to look at
|
||||
* the parents here. We also need to do the date-based limiting
|
||||
@@ -1274,6 +1290,40 @@ struct commit *get_revision(struct rev_info *revs)
|
||||
{
|
||||
struct commit *c = NULL;
|
||||
|
||||
if (revs->reverse) {
|
||||
struct commit_list *list;
|
||||
|
||||
/*
|
||||
* rev_info.reverse is used to note the fact that we
|
||||
* want to output the list of revisions in reverse
|
||||
* order. To accomplish this goal, reverse can have
|
||||
* different values:
|
||||
*
|
||||
* 0 do nothing
|
||||
* 1 reverse the list
|
||||
* 2 internal use: we have already obtained and
|
||||
* reversed the list, now we only need to yield
|
||||
* its items.
|
||||
*/
|
||||
|
||||
if (revs->reverse == 1) {
|
||||
revs->reverse = 0;
|
||||
list = NULL;
|
||||
while ((c = get_revision(revs)))
|
||||
commit_list_insert(c, &list);
|
||||
revs->commits = list;
|
||||
revs->reverse = 2;
|
||||
}
|
||||
|
||||
if (!revs->commits)
|
||||
return NULL;
|
||||
c = revs->commits->item;
|
||||
list = revs->commits->next;
|
||||
free(revs->commits);
|
||||
revs->commits = list;
|
||||
return c;
|
||||
}
|
||||
|
||||
if (0 < revs->skip_count) {
|
||||
while ((c = get_revision_1(revs)) != NULL) {
|
||||
if (revs->skip_count-- <= 0)
|
||||
|
||||
@@ -42,7 +42,8 @@ struct rev_info {
|
||||
unpacked:1, /* see also ignore_packed below */
|
||||
boundary:1,
|
||||
left_right:1,
|
||||
parents:1;
|
||||
parents:1,
|
||||
reverse:2;
|
||||
|
||||
/* Diff flags */
|
||||
unsigned int diff:1,
|
||||
@@ -89,6 +90,8 @@ struct rev_info {
|
||||
|
||||
topo_sort_set_fn_t topo_setter;
|
||||
topo_sort_get_fn_t topo_getter;
|
||||
|
||||
struct reflog_walk_info *reflog_info;
|
||||
};
|
||||
|
||||
#define REV_TREE_SAME 0
|
||||
|
||||
14
send-pack.c
14
send-pack.c
@@ -6,9 +6,9 @@
|
||||
#include "exec_cmd.h"
|
||||
|
||||
static const char send_pack_usage[] =
|
||||
"git-send-pack [--all] [--exec=git-receive-pack] <remote> [<head>...]\n"
|
||||
" --all and explicit <head> specification are mutually exclusive.";
|
||||
static const char *exec = "git-receive-pack";
|
||||
"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
|
||||
" --all and explicit <ref> specification are mutually exclusive.";
|
||||
static const char *receivepack = "git-receive-pack";
|
||||
static int verbose;
|
||||
static int send_all;
|
||||
static int force_update;
|
||||
@@ -370,8 +370,12 @@ int main(int argc, char **argv)
|
||||
char *arg = *argv;
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp(arg, "--receive-pack=", 15)) {
|
||||
receivepack = arg + 15;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exec=", 7)) {
|
||||
exec = arg + 7;
|
||||
receivepack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--all")) {
|
||||
@@ -406,7 +410,7 @@ int main(int argc, char **argv)
|
||||
usage(send_pack_usage);
|
||||
verify_remote_names(nr_heads, heads);
|
||||
|
||||
pid = git_connect(fd, dest, exec);
|
||||
pid = git_connect(fd, dest, receivepack);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
ret = send_pack(fd[0], fd[1], nr_heads, heads);
|
||||
|
||||
26
setup.c
26
setup.c
@@ -95,6 +95,8 @@ void verify_non_filename(const char *prefix, const char *arg)
|
||||
const char *name;
|
||||
struct stat st;
|
||||
|
||||
if (is_inside_git_dir())
|
||||
return;
|
||||
if (*arg == '-')
|
||||
return; /* flag */
|
||||
name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
|
||||
@@ -168,6 +170,28 @@ static int is_git_directory(const char *suspect)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int inside_git_dir = -1;
|
||||
|
||||
int is_inside_git_dir(void)
|
||||
{
|
||||
if (inside_git_dir < 0) {
|
||||
char buffer[1024];
|
||||
|
||||
if (is_bare_repository())
|
||||
return (inside_git_dir = 1);
|
||||
if (getcwd(buffer, sizeof(buffer))) {
|
||||
const char *git_dir = get_git_dir(), *cwd = buffer;
|
||||
while (*git_dir && *git_dir == *cwd) {
|
||||
git_dir++;
|
||||
cwd++;
|
||||
}
|
||||
inside_git_dir = !*git_dir;
|
||||
} else
|
||||
inside_git_dir = 0;
|
||||
}
|
||||
return inside_git_dir;
|
||||
}
|
||||
|
||||
const char *setup_git_directory_gently(int *nongit_ok)
|
||||
{
|
||||
static char cwd[PATH_MAX+1];
|
||||
@@ -214,6 +238,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
if (chdir(cwd))
|
||||
die("Cannot come back to cwd");
|
||||
setenv(GIT_DIR_ENVIRONMENT, cwd, 1);
|
||||
inside_git_dir = 1;
|
||||
return NULL;
|
||||
}
|
||||
if (nongit_ok) {
|
||||
@@ -234,6 +259,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
offset++;
|
||||
cwd[len++] = '/';
|
||||
cwd[len] = 0;
|
||||
inside_git_dir = !strncmp(cwd + offset, ".git/", 5);
|
||||
return cwd + offset;
|
||||
}
|
||||
|
||||
|
||||
40
sha1_file.c
40
sha1_file.c
@@ -1479,21 +1479,20 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
|
||||
{
|
||||
struct pack_entry e;
|
||||
|
||||
if (!find_pack_entry(sha1, &e, NULL)) {
|
||||
error("cannot read sha1_file for %s", sha1_to_hex(sha1));
|
||||
if (!find_pack_entry(sha1, &e, NULL))
|
||||
return NULL;
|
||||
}
|
||||
return unpack_entry(e.p, e.offset, type, size);
|
||||
else
|
||||
return unpack_entry(e.p, e.offset, type, size);
|
||||
}
|
||||
|
||||
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
|
||||
{
|
||||
unsigned long mapsize;
|
||||
void *map, *buf;
|
||||
struct pack_entry e;
|
||||
|
||||
if (find_pack_entry(sha1, &e, NULL))
|
||||
return read_packed_sha1(sha1, type, size);
|
||||
buf = read_packed_sha1(sha1, type, size);
|
||||
if (buf)
|
||||
return buf;
|
||||
map = map_sha1_file(sha1, &mapsize);
|
||||
if (map) {
|
||||
buf = unpack_sha1_file(map, mapsize, type, size);
|
||||
@@ -1501,9 +1500,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
|
||||
return buf;
|
||||
}
|
||||
reprepare_packed_git();
|
||||
if (find_pack_entry(sha1, &e, NULL))
|
||||
return read_packed_sha1(sha1, type, size);
|
||||
return NULL;
|
||||
return read_packed_sha1(sha1, type, size);
|
||||
}
|
||||
|
||||
void *read_object_with_reference(const unsigned char *sha1,
|
||||
@@ -1791,6 +1788,8 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
|
||||
|
||||
/* need to unpack and recompress it by itself */
|
||||
unpacked = read_packed_sha1(sha1, type, &len);
|
||||
if (!unpacked)
|
||||
error("cannot read sha1_file for %s", sha1_to_hex(sha1));
|
||||
|
||||
hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
|
||||
|
||||
@@ -2059,3 +2058,24 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_pack_header(int fd, struct pack_header *header)
|
||||
{
|
||||
char *c = (char*)header;
|
||||
ssize_t remaining = sizeof(struct pack_header);
|
||||
do {
|
||||
ssize_t r = xread(fd, c, remaining);
|
||||
if (r <= 0)
|
||||
/* "eof before pack header was fully read" */
|
||||
return PH_ERROR_EOF;
|
||||
remaining -= r;
|
||||
c += r;
|
||||
} while (remaining > 0);
|
||||
if (header->hdr_signature != htonl(PACK_SIGNATURE))
|
||||
/* "protocol error (pack signature mismatch detected)" */
|
||||
return PH_ERROR_PACK_SIGNATURE;
|
||||
if (!pack_version_ok(header->hdr_version))
|
||||
/* "protocol error (pack version unsupported)" */
|
||||
return PH_ERROR_PROTOCOL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
54
sha1_name.c
54
sha1_name.c
@@ -235,7 +235,7 @@ static int ambiguous_path(const char *path, int len)
|
||||
return slash;
|
||||
}
|
||||
|
||||
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
|
||||
{
|
||||
static const char *fmt[] = {
|
||||
"%.*s",
|
||||
@@ -246,13 +246,32 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
"refs/remotes/%.*s/HEAD",
|
||||
NULL
|
||||
};
|
||||
const char **p, *r;
|
||||
int refs_found = 0;
|
||||
|
||||
*ref = NULL;
|
||||
for (p = fmt; *p; p++) {
|
||||
unsigned char sha1_from_ref[20];
|
||||
unsigned char *this_result;
|
||||
|
||||
this_result = refs_found ? sha1_from_ref : sha1;
|
||||
r = resolve_ref(mkpath(*p, len, str), this_result, 1, NULL);
|
||||
if (r) {
|
||||
if (!refs_found++)
|
||||
*ref = xstrdup(r);
|
||||
if (!warn_ambiguous_refs)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return refs_found;
|
||||
}
|
||||
|
||||
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
{
|
||||
static const char *warning = "warning: refname '%.*s' is ambiguous.\n";
|
||||
const char **p, *ref;
|
||||
char *real_ref = NULL;
|
||||
int refs_found = 0;
|
||||
int at, reflog_len;
|
||||
unsigned char *this_result;
|
||||
unsigned char sha1_from_ref[20];
|
||||
|
||||
if (len == 40 && !get_sha1_hex(str, sha1))
|
||||
return 0;
|
||||
@@ -273,16 +292,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
if (ambiguous_path(str, len))
|
||||
return -1;
|
||||
|
||||
for (p = fmt; *p; p++) {
|
||||
this_result = refs_found ? sha1_from_ref : sha1;
|
||||
ref = resolve_ref(mkpath(*p, len, str), this_result, 1, NULL);
|
||||
if (ref) {
|
||||
if (!refs_found++)
|
||||
real_ref = xstrdup(ref);
|
||||
if (!warn_ambiguous_refs)
|
||||
break;
|
||||
}
|
||||
}
|
||||
refs_found = dwim_ref(str, len, sha1, &real_ref);
|
||||
|
||||
if (!refs_found)
|
||||
return -1;
|
||||
@@ -294,6 +304,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
/* Is it asking for N-th entry, or approxidate? */
|
||||
int nth, i;
|
||||
unsigned long at_time;
|
||||
unsigned long co_time;
|
||||
int co_tz, co_cnt;
|
||||
|
||||
for (i = nth = 0; 0 <= nth && i < reflog_len; i++) {
|
||||
char ch = str[at+2+i];
|
||||
if ('0' <= ch && ch <= '9')
|
||||
@@ -305,7 +318,18 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
at_time = 0;
|
||||
else
|
||||
at_time = approxidate(str + at + 2);
|
||||
read_ref_at(real_ref, at_time, nth, sha1);
|
||||
if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
|
||||
&co_time, &co_tz, &co_cnt)) {
|
||||
if (at_time)
|
||||
fprintf(stderr,
|
||||
"warning: Log for '%.*s' only goes "
|
||||
"back to %s.\n", len, str,
|
||||
show_rfc2822_date(co_time, co_tz));
|
||||
else
|
||||
fprintf(stderr,
|
||||
"warning: Log for '%.*s' only has "
|
||||
"%d entries.\n", len, str, co_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
free(real_ref);
|
||||
|
||||
@@ -17,7 +17,7 @@ int register_shallow(const unsigned char *sha1)
|
||||
return register_commit_graft(graft, 0);
|
||||
}
|
||||
|
||||
int is_repository_shallow()
|
||||
int is_repository_shallow(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
|
||||
@@ -106,4 +106,33 @@ test_expect_success 'read-tree' '
|
||||
cmp ../one ../original.one
|
||||
'
|
||||
|
||||
test_expect_success 'no file/rev ambuguity check inside .git' '
|
||||
cd $HERE &&
|
||||
git commit -a -m 1 &&
|
||||
cd $HERE/.git &&
|
||||
git show -s HEAD
|
||||
'
|
||||
|
||||
test_expect_success 'no file/rev ambuguity check inside a bare repo' '
|
||||
cd $HERE &&
|
||||
git clone -s --bare .git foo.git &&
|
||||
cd foo.git && GIT_DIR=. git show -s HEAD
|
||||
'
|
||||
|
||||
# This still does not work as it should...
|
||||
: test_expect_success 'no file/rev ambuguity check inside a bare repo' '
|
||||
cd $HERE &&
|
||||
git clone -s --bare .git foo.git &&
|
||||
cd foo.git && git show -s HEAD
|
||||
'
|
||||
|
||||
test_expect_success 'detection should not be fooled by a symlink' '
|
||||
cd $HERE &&
|
||||
rm -fr foo.git &&
|
||||
git clone -s .git another &&
|
||||
ln -s another yetanother &&
|
||||
cd yetanother/.git &&
|
||||
git show -s HEAD
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -418,5 +418,31 @@ EOF
|
||||
|
||||
test_expect_success 'quoting' 'cmp .git/config expect'
|
||||
|
||||
test_expect_failure 'key with newline' 'git repo-config key.with\\\
|
||||
newline 123'
|
||||
|
||||
test_expect_success 'value with newline' 'git repo-config key.sub value.with\\\
|
||||
newline'
|
||||
|
||||
cat > .git/config <<\EOF
|
||||
[section]
|
||||
; comment \
|
||||
continued = cont\
|
||||
inued
|
||||
noncont = not continued ; \
|
||||
quotecont = "cont;\
|
||||
inued"
|
||||
EOF
|
||||
|
||||
cat > expect <<\EOF
|
||||
section.continued=continued
|
||||
section.noncont=not continued
|
||||
section.quotecont=cont;inued
|
||||
EOF
|
||||
|
||||
git repo-config --list > result
|
||||
|
||||
test_expect_success 'value continued on next line' 'cmp result expect'
|
||||
|
||||
test_done
|
||||
|
||||
|
||||
@@ -138,19 +138,19 @@ test_expect_success \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{May 25 2005}" >o 2>e &&
|
||||
test '"$C"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
"Query master@{2005-05-25} (before history)" \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify master@{2005-05-25} >o 2>e &&
|
||||
test '"$C"' = $(cat o) &&
|
||||
echo test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
|
||||
test '"$C"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
|
||||
'rm -f o e
|
||||
|
||||
@@ -97,7 +97,8 @@ pull_to_client () {
|
||||
(
|
||||
mkdir client &&
|
||||
cd client &&
|
||||
git-init 2>> log2.txt
|
||||
git-init 2>> log2.txt &&
|
||||
git repo-config transfer.unpacklimit 0
|
||||
)
|
||||
|
||||
add A1
|
||||
|
||||
@@ -100,7 +100,33 @@ test_expect_success "checkout -m with dirty tree, renamed" '
|
||||
git checkout -m renamer &&
|
||||
fill 1 3 4 5 7 8 >expect &&
|
||||
diff expect uno &&
|
||||
! test -f one
|
||||
! test -f one &&
|
||||
git diff --cached >current &&
|
||||
! test -s current
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'checkout -m with merge conflict' '
|
||||
|
||||
git checkout -f master && git clean &&
|
||||
|
||||
fill 1 T 3 4 5 6 S 8 >one &&
|
||||
if git checkout renamer
|
||||
then
|
||||
echo Not happy
|
||||
false
|
||||
else
|
||||
echo "happy - failed correctly"
|
||||
fi &&
|
||||
|
||||
git checkout -m renamer &&
|
||||
|
||||
git diff master:one :3:uno |
|
||||
sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
|
||||
fill d2 aT d7 aS >expect &&
|
||||
diff current expect &&
|
||||
git diff --cached two >current &&
|
||||
! test -s current
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -761,7 +761,8 @@ int main(int argc, char **argv)
|
||||
|
||||
if (!enter_repo(dir, strict))
|
||||
die("'%s': unable to chdir or not a git archive", dir);
|
||||
|
||||
if (is_repository_shallow())
|
||||
die("attempt to fetch/clone from a shallow repository");
|
||||
upload_pack();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user