mirror of
https://github.com/git/git.git
synced 2026-04-02 04:50:12 +02:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
@@ -17,6 +17,7 @@ caret=^
|
||||
startsb=[
|
||||
endsb=]
|
||||
tilde=~
|
||||
backtick=`
|
||||
|
||||
ifdef::backend-docbook[]
|
||||
[linkgit-inlinemacro]
|
||||
|
||||
@@ -456,7 +456,9 @@ If the alias expansion is prefixed with an exclamation point,
|
||||
it will be treated as a shell command. For example, defining
|
||||
"alias.new = !gitk --all --not ORIG_HEAD", the invocation
|
||||
"git new" is equivalent to running the shell command
|
||||
"gitk --all --not ORIG_HEAD".
|
||||
"gitk --all --not ORIG_HEAD". Note that shell commands will be
|
||||
executed from the top-level directory of a repository, which may
|
||||
not necessarily be the current directory.
|
||||
|
||||
apply.whitespace::
|
||||
Tells 'git-apply' how to handle whitespaces, in the same way
|
||||
@@ -1043,6 +1045,12 @@ http.sslKey::
|
||||
over HTTPS. Can be overridden by the 'GIT_SSL_KEY' environment
|
||||
variable.
|
||||
|
||||
http.sslCertPasswordProtected::
|
||||
Enable git's password prompt for the SSL certificate. Otherwise
|
||||
OpenSSL will prompt the user, possibly many times, if the
|
||||
certificate or private key is encrypted. Can be overridden by the
|
||||
'GIT_SSL_CERT_PASSWORD_PROTECTED' environment variable.
|
||||
|
||||
http.sslCAInfo::
|
||||
File containing the certificates to verify the peer with when
|
||||
fetching or pushing over HTTPS. Can be overridden by the
|
||||
|
||||
@@ -13,7 +13,7 @@ SYNOPSIS
|
||||
[--3way] [--interactive] [--committer-date-is-author-date]
|
||||
[--ignore-date]
|
||||
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
|
||||
[--reject]
|
||||
[--reject] [-q | --quiet]
|
||||
[<mbox> | <Maildir>...]
|
||||
'git am' (--skip | --resolved | --abort)
|
||||
|
||||
@@ -39,6 +39,10 @@ OPTIONS
|
||||
--keep::
|
||||
Pass `-k` flag to 'git-mailinfo' (see linkgit:git-mailinfo[1]).
|
||||
|
||||
-q::
|
||||
--quiet::
|
||||
Be quiet. Only print error messages.
|
||||
|
||||
-u::
|
||||
--utf8::
|
||||
Pass `-u` flag to 'git-mailinfo' (see linkgit:git-mailinfo[1]).
|
||||
|
||||
@@ -164,9 +164,8 @@ to do it for you by issuing the command:
|
||||
$ git bisect skip # Current version cannot be tested
|
||||
------------
|
||||
|
||||
But computing the commit to test may be slower afterwards and git may
|
||||
eventually not be able to tell the first bad commit among a bad commit
|
||||
and one or more skipped commits.
|
||||
But git may eventually be unable to tell the first bad commit among
|
||||
a bad commit and one or more skipped commits.
|
||||
|
||||
You can even skip a range of commits, instead of just one commit,
|
||||
using the "'<commit1>'..'<commit2>'" notation. For example:
|
||||
|
||||
@@ -122,6 +122,14 @@ OPTIONS
|
||||
-<num>::
|
||||
A shortcut for specifying -C<num>.
|
||||
|
||||
-p::
|
||||
--show-function::
|
||||
Show the preceding line that contains the function name of
|
||||
the match, unless the matching line is a function name itself.
|
||||
The name is determined in the same way as 'git diff' works out
|
||||
patch hunk headers (see 'Defining a custom hunk-header' in
|
||||
linkgit:gitattributes[5]).
|
||||
|
||||
-f <file>::
|
||||
Read patterns from <file>, one per line.
|
||||
|
||||
|
||||
@@ -85,6 +85,11 @@ nor in any Push line of the corresponding remotes file---see below).
|
||||
--dry-run::
|
||||
Do everything except actually send the updates.
|
||||
|
||||
--porcelain::
|
||||
Produce machine-readable output. The output status line for each ref
|
||||
will be tab-separated and sent to stdout instead of stderr. The full
|
||||
symbolic names of the refs will be given.
|
||||
|
||||
--tags::
|
||||
All refs under `$GIT_DIR/refs/tags` are pushed, in
|
||||
addition to refspecs explicitly listed on the command
|
||||
@@ -148,6 +153,12 @@ representing the status of a single ref. Each line is of the form:
|
||||
<flag> <summary> <from> -> <to> (<reason>)
|
||||
-------------------------------
|
||||
|
||||
If --porcelain is used, then each line of the output is of the form:
|
||||
|
||||
-------------------------------
|
||||
<flag> \t <from>:<to> \t <summary> (<reason>)
|
||||
-------------------------------
|
||||
|
||||
flag::
|
||||
A single character indicating the status of the ref. This is
|
||||
blank for a successfully pushed ref, `!` for a ref that was
|
||||
|
||||
@@ -236,6 +236,10 @@ OPTIONS
|
||||
is used instead ('git-merge-recursive' when merging a single
|
||||
head, 'git-merge-octopus' otherwise). This implies --merge.
|
||||
|
||||
-q::
|
||||
--quiet::
|
||||
Be quiet. Implies --no-stat.
|
||||
|
||||
-v::
|
||||
--verbose::
|
||||
Be verbose. Implies --stat.
|
||||
|
||||
@@ -30,6 +30,11 @@ OPTIONS
|
||||
Only meaningful in `--parseopt` mode. Tells the option parser to echo
|
||||
out the first `--` met instead of skipping it.
|
||||
|
||||
--stop-at-non-option::
|
||||
Only meaningful in `--parseopt` mode. Lets the option parser stop at
|
||||
the first non-option argument. This can be used to parse sub-commands
|
||||
that take options themself.
|
||||
|
||||
--sq-quote::
|
||||
Use 'git-rev-parse' in shell quoting mode (see SQ-QUOTE
|
||||
section below). In contrast to the `--sq` option below, this
|
||||
|
||||
@@ -9,8 +9,9 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git show-ref' [-q|--quiet] [--verify] [-h|--head] [-d|--dereference]
|
||||
[-s|--hash] [--abbrev] [--tags] [--heads] [--] <pattern>...
|
||||
'git show-ref' --exclude-existing[=pattern]
|
||||
[-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
|
||||
[--heads] [--] <pattern>...
|
||||
'git show-ref' --exclude-existing[=<pattern>] < ref-list
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -48,7 +49,7 @@ OPTIONS
|
||||
appended.
|
||||
|
||||
-s::
|
||||
--hash::
|
||||
--hash[=<n>]::
|
||||
|
||||
Only show the SHA1 hash, not the reference name. When combined with
|
||||
--dereference the dereferenced tag will still be shown after the SHA1.
|
||||
@@ -59,11 +60,10 @@ OPTIONS
|
||||
Aside from returning an error code of 1, it will also print an error
|
||||
message if '--quiet' was not specified.
|
||||
|
||||
--abbrev::
|
||||
--abbrev=len::
|
||||
--abbrev[=<n>]::
|
||||
|
||||
Abbreviate the object name. When using `--hash`, you do
|
||||
not have to say `--hash --abbrev`; `--hash=len` would do.
|
||||
not have to say `--hash --abbrev`; `--hash=n` would do.
|
||||
|
||||
-q::
|
||||
--quiet::
|
||||
@@ -71,8 +71,7 @@ OPTIONS
|
||||
Do not print any results to stdout. When combined with '--verify' this
|
||||
can be used to silently check if a reference exists.
|
||||
|
||||
--exclude-existing::
|
||||
--exclude-existing=pattern::
|
||||
--exclude-existing[=<pattern>]::
|
||||
|
||||
Make 'git-show-ref' act as a filter that reads refs from stdin of the
|
||||
form "^(?:<anything>\s)?<refname>(?:\^\{\})?$" and performs the
|
||||
|
||||
@@ -9,10 +9,11 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git stash' list [<options>]
|
||||
'git stash' ( show | drop ) [<stash>]
|
||||
'git stash' ( pop | apply ) [--index] [<stash>]
|
||||
'git stash' show [<stash>]
|
||||
'git stash' drop [-q|--quiet] [<stash>]
|
||||
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
|
||||
'git stash' branch <branchname> [<stash>]
|
||||
'git stash' [save [--keep-index] [<message>]]
|
||||
'git stash' [save [--keep-index] [-q|--quiet] [<message>]]
|
||||
'git stash' clear
|
||||
'git stash' create
|
||||
|
||||
@@ -41,7 +42,7 @@ is also possible).
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
save [--keep-index] [<message>]::
|
||||
save [--keep-index] [-q|--quiet] [<message>]::
|
||||
|
||||
Save your local modifications to a new 'stash', and run `git reset
|
||||
--hard` to revert them. This is the default action when no
|
||||
@@ -75,7 +76,7 @@ show [<stash>]::
|
||||
it will accept any format known to 'git-diff' (e.g., `git stash show
|
||||
-p stash@\{1}` to view the second most recent stash in patch form).
|
||||
|
||||
pop [<stash>]::
|
||||
pop [--index] [-q|--quiet] [<stash>]::
|
||||
|
||||
Remove a single stashed state from the stash list and apply it
|
||||
on top of the current working tree state, i.e., do the inverse
|
||||
@@ -93,7 +94,7 @@ longer apply the changes as they were originally).
|
||||
+
|
||||
When no `<stash>` is given, `stash@\{0}` is assumed.
|
||||
|
||||
apply [--index] [<stash>]::
|
||||
apply [--index] [-q|--quiet] [<stash>]::
|
||||
|
||||
Like `pop`, but do not remove the state from the stash list.
|
||||
|
||||
@@ -115,7 +116,7 @@ clear::
|
||||
Remove all the stashed states. Note that those states will then
|
||||
be subject to pruning, and may be difficult or impossible to recover.
|
||||
|
||||
drop [<stash>]::
|
||||
drop [-q|--quiet] [<stash>]::
|
||||
|
||||
Remove a single stashed state from the stash list. When no `<stash>`
|
||||
is given, it removes the latest one. i.e. `stash@\{0}`
|
||||
|
||||
@@ -141,8 +141,9 @@ foreach::
|
||||
the processing to terminate. This can be overridden by adding '|| :'
|
||||
to the end of the command.
|
||||
+
|
||||
As an example, "git submodule foreach 'echo $path `git rev-parse HEAD`' will
|
||||
show the path and currently checked out commit for each submodule.
|
||||
As an example, +git submodule foreach \'echo $path {backtick}git
|
||||
rev-parse HEAD{backtick}'+ will show the path and currently checked out
|
||||
commit for each submodule.
|
||||
|
||||
sync::
|
||||
Synchronizes submodules' remote URL configuration setting
|
||||
|
||||
@@ -3,7 +3,7 @@ git-svn(1)
|
||||
|
||||
NAME
|
||||
----
|
||||
git-svn - Bidirectional operation between a single Subversion branch and git
|
||||
git-svn - Bidirectional operation between a Subversion repository and git
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
@@ -11,27 +11,25 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
'git-svn' is a simple conduit for changesets between Subversion and git.
|
||||
'git svn' is a simple conduit for changesets between Subversion and git.
|
||||
It provides a bidirectional flow of changes between a Subversion and a git
|
||||
repository.
|
||||
|
||||
'git-svn' can track a single Subversion branch simply by using a
|
||||
URL to the branch, follow branches laid out in the Subversion recommended
|
||||
method (trunk, branches, tags directories) with the --stdlayout option, or
|
||||
follow branches in any layout with the -T/-t/-b options (see options to
|
||||
'init' below, and also the 'clone' command).
|
||||
'git svn' can track a standard Subversion repository,
|
||||
following the common "trunk/branches/tags" layout, with the --stdlayout option.
|
||||
It can also follow branches and tags in any layout with the -T/-t/-b options
|
||||
(see options to 'init' below, and also the 'clone' command).
|
||||
|
||||
Once tracking a Subversion branch (with any of the above methods), the git
|
||||
Once tracking a Subversion repository (with any of the above methods), the git
|
||||
repository can be updated from Subversion by the 'fetch' command and
|
||||
Subversion updated from git by the 'dcommit' command.
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
--
|
||||
|
||||
'init'::
|
||||
Initializes an empty git repository with additional
|
||||
metadata directories for 'git-svn'. The Subversion URL
|
||||
metadata directories for 'git svn'. The Subversion URL
|
||||
may be specified as a command-line argument, or as full
|
||||
URL arguments to -T/-t/-b. Optionally, the target
|
||||
directory to operate on can be specified as a second
|
||||
@@ -48,8 +46,11 @@ COMMANDS
|
||||
--stdlayout;;
|
||||
These are optional command-line options for init. Each of
|
||||
these flags can point to a relative repository path
|
||||
(--tags=project/tags') or a full url
|
||||
(--tags=https://foo.org/project/tags). The option --stdlayout is
|
||||
(--tags=project/tags) or a full url
|
||||
(--tags=https://foo.org/project/tags).
|
||||
You can specify more than one --tags and/or --branches options, in case
|
||||
your Subversion repository places tags or branches under multiple paths.
|
||||
The option --stdlayout is
|
||||
a shorthand way of setting trunk,tags,branches as the relative paths,
|
||||
which is the Subversion default. If any of the other options are given
|
||||
as well, they take precedence.
|
||||
@@ -61,16 +62,6 @@ COMMANDS
|
||||
Set the 'useSvnsyncProps' option in the [svn-remote] config.
|
||||
--rewrite-root=<URL>;;
|
||||
Set the 'rewriteRoot' option in the [svn-remote] config.
|
||||
--use-log-author;;
|
||||
When retrieving svn commits into git (as part of fetch, rebase, or
|
||||
dcommit operations), look for the first From: or Signed-off-by: line
|
||||
in the log message and use that as the author string.
|
||||
--add-author-from;;
|
||||
When committing to svn from git (as part of commit or dcommit
|
||||
operations), if the existing log message doesn't already have a
|
||||
From: or Signed-off-by: line, append a From: line based on the
|
||||
git commit's author string. If you use this, then --use-log-author
|
||||
will retrieve a valid author string for all commits.
|
||||
--username=<USER>;;
|
||||
For transports that SVN handles authentication for (http,
|
||||
https, and plain svn), specify the username. For other
|
||||
@@ -98,12 +89,12 @@ COMMANDS
|
||||
|
||||
--localtime;;
|
||||
Store Git commit times in the local timezone instead of UTC. This
|
||||
makes 'git-log' (even without --date=local) show the same times
|
||||
makes 'git log' (even without --date=local) show the same times
|
||||
that `svn log` would in the local timezone.
|
||||
|
||||
--parent;;
|
||||
Fetch only from the SVN parent of the current HEAD.
|
||||
|
||||
+
|
||||
This doesn't interfere with interoperating with the Subversion
|
||||
repository you cloned from, but if you wish for your local Git
|
||||
repository to be able to interoperate with someone else's local Git
|
||||
@@ -116,20 +107,39 @@ the same local timezone.
|
||||
The '--ignore-paths' option should match for every 'fetch'
|
||||
(including automatic fetches due to 'clone', 'dcommit',
|
||||
'rebase', etc) on a given repository.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn-remote.<name>.ignore-paths
|
||||
|
||||
If the ignore-paths config key is set and the command
|
||||
line option is also given, both regular expressions
|
||||
will be used.
|
||||
|
||||
+
|
||||
If the ignore-paths config key is set and the command line option is
|
||||
also given, both regular expressions will be used.
|
||||
+
|
||||
Examples:
|
||||
+
|
||||
--
|
||||
Skip "doc*" directory for every fetch;;
|
||||
+
|
||||
------------------------------------------------------------------------
|
||||
--ignore-paths="^doc"
|
||||
------------------------------------------------------------------------
|
||||
|
||||
--ignore-paths="^doc" - skip "doc*" directory for every
|
||||
fetch.
|
||||
Skip "branches" and "tags" of first level directories;;
|
||||
+
|
||||
------------------------------------------------------------------------
|
||||
--ignore-paths="^[^/]+/(?:branches|tags)"
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
|
||||
--ignore-paths="^[^/]+/(?:branches|tags)" - skip
|
||||
"branches" and "tags" of first level directories.
|
||||
--use-log-author;;
|
||||
When retrieving svn commits into git (as part of fetch, rebase, or
|
||||
dcommit operations), look for the first From: or Signed-off-by: line
|
||||
in the log message and use that as the author string.
|
||||
--add-author-from;;
|
||||
When committing to svn from git (as part of commit or dcommit
|
||||
operations), if the existing log message doesn't already have a
|
||||
From: or Signed-off-by: line, append a From: line based on the
|
||||
git commit's author string. If you use this, then --use-log-author
|
||||
will retrieve a valid author string for all commits.
|
||||
|
||||
'clone'::
|
||||
Runs 'init' and 'fetch'. It will automatically create a
|
||||
@@ -137,29 +147,29 @@ Examples:
|
||||
or if a second argument is passed; it will create a directory
|
||||
and work within that. It accepts all arguments that the
|
||||
'init' and 'fetch' commands accept; with the exception of
|
||||
'--fetch-all'. After a repository is cloned, the 'fetch'
|
||||
command will be able to update revisions without affecting
|
||||
the working tree; and the 'rebase' command will be able
|
||||
to update the working tree with the latest changes.
|
||||
'--fetch-all' and '--parent'. After a repository is cloned,
|
||||
the 'fetch' command will be able to update revisions without
|
||||
affecting the working tree; and the 'rebase' command will be
|
||||
able to update the working tree with the latest changes.
|
||||
|
||||
'rebase'::
|
||||
This fetches revisions from the SVN parent of the current HEAD
|
||||
and rebases the current (uncommitted to SVN) work against it.
|
||||
|
||||
This works similarly to `svn update` or 'git-pull' except that
|
||||
it preserves linear history with 'git-rebase' instead of
|
||||
'git-merge' for ease of dcommitting with 'git-svn'.
|
||||
|
||||
This accepts all options that 'git-svn fetch' and 'git-rebase'
|
||||
+
|
||||
This works similarly to `svn update` or 'git pull' except that
|
||||
it preserves linear history with 'git rebase' instead of
|
||||
'git merge' for ease of dcommitting with 'git svn'.
|
||||
+
|
||||
This accepts all options that 'git svn fetch' and 'git rebase'
|
||||
accept. However, '--fetch-all' only fetches from the current
|
||||
[svn-remote], and not all [svn-remote] definitions.
|
||||
|
||||
Like 'git-rebase'; this requires that the working tree be clean
|
||||
+
|
||||
Like 'git rebase'; this requires that the working tree be clean
|
||||
and have no uncommitted changes.
|
||||
|
||||
-l;;
|
||||
--local;;
|
||||
Do not fetch remotely; only run 'git-rebase' against the
|
||||
Do not fetch remotely; only run 'git rebase' against the
|
||||
last fetched commit from the upstream SVN.
|
||||
|
||||
'dcommit'::
|
||||
@@ -167,11 +177,12 @@ and have no uncommitted changes.
|
||||
repository, and then rebase or reset (depending on whether or
|
||||
not there is a diff between SVN and head). This will create
|
||||
a revision in SVN for each commit in git.
|
||||
It is recommended that you run 'git-svn' fetch and rebase (not
|
||||
It is recommended that you run 'git svn' fetch and rebase (not
|
||||
pull or merge) your commits against the latest changes in the
|
||||
SVN repository.
|
||||
An optional command-line argument may be specified as an
|
||||
alternative to HEAD.
|
||||
An optional revision or branch argument may be specified, and
|
||||
causes 'git svn' to do all work on that revision/branch
|
||||
instead of HEAD.
|
||||
This is advantageous over 'set-tree' (below) because it produces
|
||||
cleaner, more linear history.
|
||||
+
|
||||
@@ -179,18 +190,17 @@ and have no uncommitted changes.
|
||||
After committing, do not rebase or reset.
|
||||
--commit-url <URL>;;
|
||||
Commit to this SVN URL (the full path). This is intended to
|
||||
allow existing git-svn repositories created with one transport
|
||||
allow existing 'git svn' repositories created with one transport
|
||||
method (e.g. `svn://` or `http://` for anonymous read) to be
|
||||
reused if a user is later given access to an alternate transport
|
||||
method (e.g. `svn+ssh://` or `https://`) for commit.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn-remote.<name>.commiturl
|
||||
|
||||
config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
|
||||
|
||||
Using this option for any other purpose (don't ask)
|
||||
is very strongly discouraged.
|
||||
--
|
||||
+
|
||||
Using this option for any other purpose (don't ask) is very strongly
|
||||
discouraged.
|
||||
|
||||
'branch'::
|
||||
Create a branch in the SVN repository.
|
||||
@@ -204,6 +214,20 @@ config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
|
||||
Create a tag by using the tags_subdir instead of the branches_subdir
|
||||
specified during git svn init.
|
||||
|
||||
-d;;
|
||||
--destination;;
|
||||
If more than one --branches (or --tags) option was given to the 'init'
|
||||
or 'clone' command, you must provide the location of the branch (or
|
||||
tag) you wish to create in the SVN repository. The value of this
|
||||
option must match one of the paths specified by a --branches (or
|
||||
--tags) option. You can see these paths with the commands
|
||||
+
|
||||
git config --get-all svn-remote.<name>.branches
|
||||
git config --get-all svn-remote.<name>.tags
|
||||
+
|
||||
where <name> is the name of the SVN repository as specified by the -R option to
|
||||
'init' (or "svn" by default).
|
||||
|
||||
'tag'::
|
||||
Create a tag in the SVN repository. This is a shorthand for
|
||||
'branch -t'.
|
||||
@@ -215,10 +239,12 @@ config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
|
||||
The following features from `svn log' are supported:
|
||||
+
|
||||
--
|
||||
-r <n>[:<n>];;
|
||||
--revision=<n>[:<n>];;
|
||||
is supported, non-numeric args are not:
|
||||
HEAD, NEXT, BASE, PREV, etc ...
|
||||
-v/--verbose;;
|
||||
-v;;
|
||||
--verbose;;
|
||||
it's not completely compatible with the --verbose
|
||||
output in svn log, but reasonably close.
|
||||
--limit=<n>;;
|
||||
@@ -241,7 +267,7 @@ NOTE: SVN itself only stores times in UTC and nothing else. The regular svn
|
||||
client converts the UTC time to the local time (or based on the TZ=
|
||||
environment). This command has the same behaviour.
|
||||
+
|
||||
Any other arguments are passed directly to 'git-log'
|
||||
Any other arguments are passed directly to 'git log'
|
||||
|
||||
'blame'::
|
||||
Show what revision and author last modified each line of a file. The
|
||||
@@ -249,15 +275,14 @@ Any other arguments are passed directly to 'git-log'
|
||||
`svn blame' by default. Like the SVN blame command,
|
||||
local uncommitted changes in the working copy are ignored;
|
||||
the version of the file in the HEAD revision is annotated. Unknown
|
||||
arguments are passed directly to 'git-blame'.
|
||||
arguments are passed directly to 'git blame'.
|
||||
+
|
||||
--git-format;;
|
||||
Produce output in the same format as 'git-blame', but with
|
||||
Produce output in the same format as 'git blame', but with
|
||||
SVN revision numbers instead of git commit hashes. In this mode,
|
||||
changes that haven't been committed to SVN (including local
|
||||
working-copy edits) are shown as revision 0.
|
||||
|
||||
--
|
||||
'find-rev'::
|
||||
When given an SVN revision number of the form 'rN', returns the
|
||||
corresponding git commit hash (this can optionally be followed by a
|
||||
@@ -271,7 +296,7 @@ Any other arguments are passed directly to 'git-log'
|
||||
absolutely no attempts to do patching when committing to SVN, it
|
||||
simply overwrites files with those specified in the tree or
|
||||
commit. All merging is assumed to have taken place
|
||||
independently of 'git-svn' functions.
|
||||
independently of 'git svn' functions.
|
||||
|
||||
'create-ignore'::
|
||||
Recursively finds the svn:ignore property on directories and
|
||||
@@ -286,12 +311,12 @@ Any other arguments are passed directly to 'git-log'
|
||||
|
||||
'commit-diff'::
|
||||
Commits the diff of two tree-ish arguments from the
|
||||
command-line. This command does not rely on being inside an `git-svn
|
||||
command-line. This command does not rely on being inside an `git svn
|
||||
init`-ed repository. This command takes three arguments, (a) the
|
||||
original tree to diff against, (b) the new tree result, (c) the
|
||||
URL of the target Subversion repository. The final argument
|
||||
(URL) may be omitted if you are working from a 'git-svn'-aware
|
||||
repository (that has been `init`-ed with 'git-svn').
|
||||
(URL) may be omitted if you are working from a 'git svn'-aware
|
||||
repository (that has been `init`-ed with 'git svn').
|
||||
The -r<revision> option is required for this.
|
||||
|
||||
'info'::
|
||||
@@ -313,116 +338,166 @@ Any other arguments are passed directly to 'git-log'
|
||||
Shows the Subversion externals. Use -r/--revision to specify a
|
||||
specific revision.
|
||||
|
||||
--
|
||||
'reset'::
|
||||
Undoes the effects of 'fetch' back to the specified revision.
|
||||
This allows you to re-'fetch' an SVN revision. Normally the
|
||||
contents of an SVN revision should never change and 'reset'
|
||||
should not be necessary. However, if SVN permissions change,
|
||||
or if you alter your --ignore-paths option, a 'fetch' may fail
|
||||
with "not found in commit" (file not previously visible) or
|
||||
"checksum mismatch" (missed a modification). If the problem
|
||||
file cannot be ignored forever (with --ignore-paths) the only
|
||||
way to repair the repo is to use 'reset'.
|
||||
+
|
||||
Only the rev_map and refs/remotes/git-svn are changed. Follow 'reset'
|
||||
with a 'fetch' and then 'git reset' or 'git rebase' to move local
|
||||
branches onto the new tree.
|
||||
|
||||
-r <n>;;
|
||||
--revision=<n>;;
|
||||
Specify the most recent revision to keep. All later revisions
|
||||
are discarded.
|
||||
-p;;
|
||||
--parent;;
|
||||
Discard the specified revision as well, keeping the nearest
|
||||
parent instead.
|
||||
Example:;;
|
||||
Assume you have local changes in "master", but you need to refetch "r2".
|
||||
+
|
||||
------------
|
||||
r1---r2---r3 remotes/git-svn
|
||||
\
|
||||
A---B master
|
||||
------------
|
||||
+
|
||||
Fix the ignore-paths or SVN permissions problem that caused "r2" to
|
||||
be incomplete in the first place. Then:
|
||||
+
|
||||
[verse]
|
||||
git svn reset -r2 -p
|
||||
git svn fetch
|
||||
+
|
||||
------------
|
||||
r1---r2'--r3' remotes/git-svn
|
||||
\
|
||||
r2---r3---A---B master
|
||||
------------
|
||||
+
|
||||
Then fixup "master" with 'git rebase'.
|
||||
Do NOT use 'git merge' or your history will not be compatible with a
|
||||
future 'dcommit'!
|
||||
+
|
||||
[verse]
|
||||
git rebase --onto remotes/git-svn A^ master
|
||||
+
|
||||
------------
|
||||
r1---r2'--r3' remotes/git-svn
|
||||
\
|
||||
A'--B' master
|
||||
------------
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--
|
||||
|
||||
--shared[={false|true|umask|group|all|world|everybody}]::
|
||||
--template=<template_directory>::
|
||||
Only used with the 'init' command.
|
||||
These are passed directly to 'git-init'.
|
||||
These are passed directly to 'git init'.
|
||||
|
||||
-r <ARG>::
|
||||
--revision <ARG>::
|
||||
|
||||
Used with the 'fetch' command.
|
||||
|
||||
Used with the 'fetch' command.
|
||||
+
|
||||
This allows revision ranges for partial/cauterized history
|
||||
to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges),
|
||||
$NUMBER:HEAD, and BASE:$NUMBER are all supported.
|
||||
|
||||
+
|
||||
This can allow you to make partial mirrors when running fetch;
|
||||
but is generally not recommended because history will be skipped
|
||||
and lost.
|
||||
|
||||
-::
|
||||
--stdin::
|
||||
|
||||
Only used with the 'set-tree' command.
|
||||
|
||||
Only used with the 'set-tree' command.
|
||||
+
|
||||
Read a list of commits from stdin and commit them in reverse
|
||||
order. Only the leading sha1 is read from each line, so
|
||||
'git-rev-list --pretty=oneline' output can be used.
|
||||
'git rev-list --pretty=oneline' output can be used.
|
||||
|
||||
--rmdir::
|
||||
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
+
|
||||
Remove directories from the SVN tree if there are no files left
|
||||
behind. SVN can version empty directories, and they are not
|
||||
removed by default if there are no files left in them. git
|
||||
cannot version empty directories. Enabling this flag will make
|
||||
the commit to SVN act like git.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn.rmdir
|
||||
|
||||
-e::
|
||||
--edit::
|
||||
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
+
|
||||
Edit the commit message before committing to SVN. This is off by
|
||||
default for objects that are commits, and forced on when committing
|
||||
tree objects.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn.edit
|
||||
|
||||
-l<num>::
|
||||
--find-copies-harder::
|
||||
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
|
||||
They are both passed directly to 'git-diff-tree'; see
|
||||
Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
|
||||
+
|
||||
They are both passed directly to 'git diff-tree'; see
|
||||
linkgit:git-diff-tree[1] for more information.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn.l
|
||||
config key: svn.findcopiesharder
|
||||
|
||||
-A<filename>::
|
||||
--authors-file=<filename>::
|
||||
|
||||
Syntax is compatible with the file used by 'git-cvsimport':
|
||||
|
||||
Syntax is compatible with the file used by 'git cvsimport':
|
||||
+
|
||||
------------------------------------------------------------------------
|
||||
loginname = Joe User <user@example.com>
|
||||
------------------------------------------------------------------------
|
||||
|
||||
If this option is specified and 'git-svn' encounters an SVN
|
||||
committer name that does not exist in the authors-file, 'git-svn'
|
||||
+
|
||||
If this option is specified and 'git svn' encounters an SVN
|
||||
committer name that does not exist in the authors-file, 'git svn'
|
||||
will abort operation. The user will then have to add the
|
||||
appropriate entry. Re-running the previous 'git-svn' command
|
||||
appropriate entry. Re-running the previous 'git svn' command
|
||||
after the authors-file is modified should continue operation.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn.authorsfile
|
||||
|
||||
--authors-prog=<filename>::
|
||||
|
||||
If this option is specified, for each SVN committer name that does not
|
||||
exist in the authors file, the given file is executed with the committer
|
||||
name as the first argument. The program is expected to return a single
|
||||
line of the form "Name <email>", which will be treated as if included in
|
||||
the authors file.
|
||||
If this option is specified, for each SVN committer name that
|
||||
does not exist in the authors file, the given file is executed
|
||||
with the committer name as the first argument. The program is
|
||||
expected to return a single line of the form "Name <email>",
|
||||
which will be treated as if included in the authors file.
|
||||
|
||||
-q::
|
||||
--quiet::
|
||||
Make 'git-svn' less verbose. Specify a second time to make it
|
||||
Make 'git svn' less verbose. Specify a second time to make it
|
||||
even less verbose.
|
||||
|
||||
--repack[=<n>]::
|
||||
--repack-flags=<flags>::
|
||||
|
||||
These should help keep disk usage sane for large fetches
|
||||
with many revisions.
|
||||
|
||||
These should help keep disk usage sane for large fetches with
|
||||
many revisions.
|
||||
+
|
||||
--repack takes an optional argument for the number of revisions
|
||||
to fetch before repacking. This defaults to repacking every
|
||||
1000 commits fetched if no argument is specified.
|
||||
|
||||
--repack-flags are passed directly to 'git-repack'.
|
||||
|
||||
+
|
||||
--repack-flags are passed directly to 'git repack'.
|
||||
+
|
||||
[verse]
|
||||
config key: svn.repack
|
||||
config key: svn.repackflags
|
||||
@@ -431,41 +506,36 @@ config key: svn.repackflags
|
||||
--merge::
|
||||
-s<strategy>::
|
||||
--strategy=<strategy>::
|
||||
|
||||
These are only used with the 'dcommit' and 'rebase' commands.
|
||||
|
||||
Passed directly to 'git-rebase' when using 'dcommit' if a
|
||||
'git-reset' cannot be used (see 'dcommit').
|
||||
These are only used with the 'dcommit' and 'rebase' commands.
|
||||
+
|
||||
Passed directly to 'git rebase' when using 'dcommit' if a
|
||||
'git reset' cannot be used (see 'dcommit').
|
||||
|
||||
-n::
|
||||
--dry-run::
|
||||
|
||||
This can be used with the 'dcommit', 'rebase', 'branch' and 'tag'
|
||||
commands.
|
||||
|
||||
This can be used with the 'dcommit', 'rebase', 'branch' and
|
||||
'tag' commands.
|
||||
+
|
||||
For 'dcommit', print out the series of git arguments that would show
|
||||
which diffs would be committed to SVN.
|
||||
|
||||
+
|
||||
For 'rebase', display the local branch associated with the upstream svn
|
||||
repository associated with the current branch and the URL of svn
|
||||
repository that will be fetched from.
|
||||
|
||||
+
|
||||
For 'branch' and 'tag', display the urls that will be used for copying when
|
||||
creating the branch or tag.
|
||||
|
||||
--
|
||||
|
||||
ADVANCED OPTIONS
|
||||
----------------
|
||||
--
|
||||
|
||||
-i<GIT_SVN_ID>::
|
||||
--id <GIT_SVN_ID>::
|
||||
|
||||
This sets GIT_SVN_ID (instead of using the environment). This
|
||||
allows the user to override the default refname to fetch from
|
||||
when tracking a single URL. The 'log' and 'dcommit' commands
|
||||
no longer require this switch as an argument.
|
||||
This sets GIT_SVN_ID (instead of using the environment). This
|
||||
allows the user to override the default refname to fetch from
|
||||
when tracking a single URL. The 'log' and 'dcommit' commands
|
||||
no longer require this switch as an argument.
|
||||
|
||||
-R<remote name>::
|
||||
--svn-remote <remote name>::
|
||||
@@ -479,33 +549,30 @@ no longer require this switch as an argument.
|
||||
started tracking a branch and never tracked the trunk it was
|
||||
descended from. This feature is enabled by default, use
|
||||
--no-follow-parent to disable it.
|
||||
|
||||
+
|
||||
[verse]
|
||||
config key: svn.followparent
|
||||
|
||||
--
|
||||
CONFIG FILE-ONLY OPTIONS
|
||||
------------------------
|
||||
--
|
||||
|
||||
svn.noMetadata::
|
||||
svn-remote.<name>.noMetadata::
|
||||
|
||||
This gets rid of the 'git-svn-id:' lines at the end of every commit.
|
||||
|
||||
If you lose your .git/svn/git-svn/.rev_db file, 'git-svn' will not
|
||||
This gets rid of the 'git-svn-id:' lines at the end of every commit.
|
||||
+
|
||||
If you lose your .git/svn/git-svn/.rev_db file, 'git svn' will not
|
||||
be able to rebuild it and you won't be able to fetch again,
|
||||
either. This is fine for one-shot imports.
|
||||
|
||||
The 'git-svn log' command will not work on repositories using
|
||||
+
|
||||
The 'git svn log' command will not work on repositories using
|
||||
this, either. Using this conflicts with the 'useSvmProps'
|
||||
option for (hopefully) obvious reasons.
|
||||
|
||||
svn.useSvmProps::
|
||||
svn-remote.<name>.useSvmProps::
|
||||
|
||||
This allows 'git-svn' to re-map repository URLs and UUIDs from
|
||||
mirrors created using SVN::Mirror (or svk) for metadata.
|
||||
|
||||
This allows 'git svn' to re-map repository URLs and UUIDs from
|
||||
mirrors created using SVN::Mirror (or svk) for metadata.
|
||||
+
|
||||
If an SVN revision has a property, "svm:headrev", it is likely
|
||||
that the revision was created by SVN::Mirror (also used by SVK).
|
||||
The property contains a repository UUID and a revision. We want
|
||||
@@ -522,23 +589,22 @@ svn-remote.<name>.useSvnsyncprops::
|
||||
|
||||
svn-remote.<name>.rewriteRoot::
|
||||
This allows users to create repositories from alternate
|
||||
URLs. For example, an administrator could run 'git-svn' on the
|
||||
URLs. For example, an administrator could run 'git svn' on the
|
||||
server locally (accessing via file://) but wish to distribute
|
||||
the repository with a public http:// or svn:// URL in the
|
||||
metadata so users of it will see the public URL.
|
||||
|
||||
svn.brokenSymlinkWorkaround::
|
||||
This disables potentially expensive checks to workaround broken symlinks
|
||||
checked into SVN by broken clients. Set this option to "false" if you
|
||||
track a SVN repository with many empty blobs that are not symlinks.
|
||||
This option may be changed while "git-svn" is running and take effect on
|
||||
the next revision fetched. If unset, git-svn assumes this option to be
|
||||
"true".
|
||||
|
||||
--
|
||||
This disables potentially expensive checks to workaround
|
||||
broken symlinks checked into SVN by broken clients. Set this
|
||||
option to "false" if you track a SVN repository with many
|
||||
empty blobs that are not symlinks. This option may be changed
|
||||
while 'git svn' is running and take effect on the next
|
||||
revision fetched. If unset, 'git svn' assumes this option to
|
||||
be "true".
|
||||
|
||||
Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps
|
||||
options all affect the metadata generated and used by 'git-svn'; they
|
||||
options all affect the metadata generated and used by 'git svn'; they
|
||||
*must* be set in the configuration file before any history is imported
|
||||
and these settings should never be changed once they are set.
|
||||
|
||||
@@ -556,7 +622,7 @@ Tracking and contributing to the trunk of a Subversion-managed project:
|
||||
git svn clone http://svn.example.com/project/trunk
|
||||
# Enter the newly cloned directory:
|
||||
cd trunk
|
||||
# You should be on master branch, double-check with git-branch
|
||||
# You should be on master branch, double-check with 'git branch'
|
||||
git branch
|
||||
# Do some work and commit locally to git:
|
||||
git commit ...
|
||||
@@ -587,12 +653,12 @@ Tracking and contributing to an entire Subversion-managed project
|
||||
# of dcommit/rebase/show-ignore should be the same as above.
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The initial 'git-svn clone' can be quite time-consuming
|
||||
The initial 'git svn clone' can be quite time-consuming
|
||||
(especially for large Subversion repositories). If multiple
|
||||
people (or one person with multiple machines) want to use
|
||||
'git-svn' to interact with the same Subversion repository, you can
|
||||
do the initial 'git-svn clone' to a repository on a server and
|
||||
have each person clone that repository with 'git-clone':
|
||||
'git svn' to interact with the same Subversion repository, you can
|
||||
do the initial 'git svn clone' to a repository on a server and
|
||||
have each person clone that repository with 'git clone':
|
||||
|
||||
------------------------------------------------------------------------
|
||||
# Do the initial import on a server
|
||||
@@ -606,7 +672,7 @@ have each person clone that repository with 'git-clone':
|
||||
git fetch
|
||||
# Create a local branch from one of the branches just fetched
|
||||
git checkout -b master FETCH_HEAD
|
||||
# Initialize git-svn locally (be sure to use the same URL and -T/-b/-t options as were used on server)
|
||||
# Initialize 'git svn' locally (be sure to use the same URL and -T/-b/-t options as were used on server)
|
||||
git svn init http://svn.example.com/project
|
||||
# Pull the latest changes from Subversion
|
||||
git svn rebase
|
||||
@@ -615,7 +681,7 @@ have each person clone that repository with 'git-clone':
|
||||
REBASE VS. PULL/MERGE
|
||||
---------------------
|
||||
|
||||
Originally, 'git-svn' recommended that the 'remotes/git-svn' branch be
|
||||
Originally, 'git svn' recommended that the 'remotes/git-svn' branch be
|
||||
pulled or merged from. This is because the author favored
|
||||
`git svn set-tree B` to commit a single head rather than the
|
||||
`git svn set-tree A..B` notation to commit multiple commits.
|
||||
@@ -630,7 +696,7 @@ previous commits in SVN.
|
||||
DESIGN PHILOSOPHY
|
||||
-----------------
|
||||
Merge tracking in Subversion is lacking and doing branched development
|
||||
with Subversion can be cumbersome as a result. While 'git-svn' can track
|
||||
with Subversion can be cumbersome as a result. While 'git svn' can track
|
||||
copy history (including branches and tags) for repositories adopting a
|
||||
standard layout, it cannot yet represent merge history that happened
|
||||
inside git back upstream to SVN users. Therefore it is advised that
|
||||
@@ -641,25 +707,25 @@ CAVEATS
|
||||
-------
|
||||
|
||||
For the sake of simplicity and interoperating with a less-capable system
|
||||
(SVN), it is recommended that all 'git-svn' users clone, fetch and dcommit
|
||||
directly from the SVN server, and avoid all 'git-clone'/'pull'/'merge'/'push'
|
||||
(SVN), it is recommended that all 'git svn' users clone, fetch and dcommit
|
||||
directly from the SVN server, and avoid all 'git clone'/'pull'/'merge'/'push'
|
||||
operations between git repositories and branches. The recommended
|
||||
method of exchanging code between git branches and users is
|
||||
'git-format-patch' and 'git-am', or just 'dcommit'ing to the SVN repository.
|
||||
'git format-patch' and 'git am', or just 'dcommit'ing to the SVN repository.
|
||||
|
||||
Running 'git-merge' or 'git-pull' is NOT recommended on a branch you
|
||||
Running 'git merge' or 'git pull' is NOT recommended on a branch you
|
||||
plan to 'dcommit' from. Subversion does not represent merges in any
|
||||
reasonable or useful fashion; so users using Subversion cannot see any
|
||||
merges you've made. Furthermore, if you merge or pull from a git branch
|
||||
that is a mirror of an SVN branch, 'dcommit' may commit to the wrong
|
||||
branch.
|
||||
|
||||
'git-clone' does not clone branches under the refs/remotes/ hierarchy or
|
||||
any 'git-svn' metadata, or config. So repositories created and managed with
|
||||
using 'git-svn' should use 'rsync' for cloning, if cloning is to be done
|
||||
'git clone' does not clone branches under the refs/remotes/ hierarchy or
|
||||
any 'git svn' metadata, or config. So repositories created and managed with
|
||||
using 'git svn' should use 'rsync' for cloning, if cloning is to be done
|
||||
at all.
|
||||
|
||||
Since 'dcommit' uses rebase internally, any git branches you 'git-push' to
|
||||
Since 'dcommit' uses rebase internally, any git branches you 'git push' to
|
||||
before 'dcommit' on will require forcing an overwrite of the existing ref
|
||||
on the remote repository. This is generally considered bad practice,
|
||||
see the linkgit:git-push[1] documentation for details.
|
||||
@@ -669,6 +735,16 @@ already dcommitted. It is considered bad practice to --amend commits
|
||||
you've already pushed to a remote repository for other users, and
|
||||
dcommit with SVN is analogous to that.
|
||||
|
||||
When using multiple --branches or --tags, 'git svn' does not automatically
|
||||
handle name collisions (for example, if two branches from different paths have
|
||||
the same name, or if a branch and a tag have the same name). In these cases,
|
||||
use 'init' to set up your git repository then, before your first 'fetch', edit
|
||||
the .git/config file so that the branches and tags are associated with
|
||||
different name spaces. For example:
|
||||
|
||||
branches = stable/*:refs/remotes/svn/stable/*
|
||||
branches = debug/*:refs/remotes/svn/debug/*
|
||||
|
||||
BUGS
|
||||
----
|
||||
|
||||
@@ -685,7 +761,7 @@ for git to detect them.
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
'git-svn' stores [svn-remote] configuration information in the
|
||||
'git svn' stores [svn-remote] configuration information in the
|
||||
repository .git/config file. It is similar the core git
|
||||
[remote] sections except 'fetch' keys do not accept glob
|
||||
arguments; but they are instead handled by the 'branches'
|
||||
@@ -706,7 +782,7 @@ Keep in mind that the '\*' (asterisk) wildcard of the local ref
|
||||
however the remote wildcard may be anywhere as long as it's an
|
||||
independent path component (surrounded by '/' or EOL). This
|
||||
type of configuration is not automatically created by 'init' and
|
||||
should be manually entered with a text-editor or using 'git-config'.
|
||||
should be manually entered with a text-editor or using 'git config'.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
@@ -332,11 +332,11 @@ alice$ git log -p HEAD..FETCH_HEAD
|
||||
------------------------------------------------
|
||||
|
||||
This operation is safe even if Alice has uncommitted local changes.
|
||||
The range notation HEAD..FETCH_HEAD" means "show everything that is reachable
|
||||
from the FETCH_HEAD but exclude anything that is reachable from HEAD.
|
||||
The range notation "HEAD..FETCH_HEAD" means "show everything that is reachable
|
||||
from the FETCH_HEAD but exclude anything that is reachable from HEAD".
|
||||
Alice already knows everything that leads to her current state (HEAD),
|
||||
and reviewing what Bob has in his state (FETCH_HEAD) that she has not
|
||||
seen with this command
|
||||
and reviews what Bob has in his state (FETCH_HEAD) that she has not
|
||||
seen with this command.
|
||||
|
||||
If Alice wants to visualize what Bob did since their histories forked
|
||||
she can issue the following command:
|
||||
@@ -375,9 +375,9 @@ it easier:
|
||||
alice$ git remote add bob /home/bob/myrepo
|
||||
------------------------------------------------
|
||||
|
||||
With this, Alice can perform the first part of the "pull" operation alone using the
|
||||
'git-fetch' command without merging them with her own branch,
|
||||
using:
|
||||
With this, Alice can perform the first part of the "pull" operation
|
||||
alone using the 'git-fetch' command without merging them with her own
|
||||
branch, using:
|
||||
|
||||
-------------------------------------
|
||||
alice$ git fetch bob
|
||||
@@ -566,22 +566,22 @@ $ git log v2.5.. Makefile # commits since v2.5 which modify
|
||||
|
||||
You can also give 'git-log' a "range" of commits where the first is not
|
||||
necessarily an ancestor of the second; for example, if the tips of
|
||||
the branches "stable-release" and "master" diverged from a common
|
||||
the branches "stable" and "master" diverged from a common
|
||||
commit some time ago, then
|
||||
|
||||
-------------------------------------
|
||||
$ git log stable..experimental
|
||||
$ git log stable..master
|
||||
-------------------------------------
|
||||
|
||||
will list commits made in the experimental branch but not in the
|
||||
will list commits made in the master branch but not in the
|
||||
stable branch, while
|
||||
|
||||
-------------------------------------
|
||||
$ git log experimental..stable
|
||||
$ git log master..stable
|
||||
-------------------------------------
|
||||
|
||||
will show the list of commits made on the stable branch but not
|
||||
the experimental branch.
|
||||
the master branch.
|
||||
|
||||
The 'git-log' command has a weakness: it must present commits in a
|
||||
list. When the history has lines of development that diverged and
|
||||
|
||||
30
Makefile
30
Makefile
@@ -194,6 +194,8 @@ all::
|
||||
#
|
||||
# Define USE_NED_ALLOCATOR if you want to replace the platforms default
|
||||
# memory allocators with the nedmalloc allocator written by Niall Douglas.
|
||||
#
|
||||
# Define NO_REGEX if you have no or inferior regex support in your C library.
|
||||
|
||||
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||
@@ -723,6 +725,7 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
ifeq ($(uname_R),5.7)
|
||||
NEEDS_RESOLV = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
@@ -750,7 +753,7 @@ ifeq ($(uname_S),SunOS)
|
||||
endif
|
||||
INSTALL = /usr/ucb/install
|
||||
TAR = gtar
|
||||
BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__
|
||||
BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
|
||||
endif
|
||||
ifeq ($(uname_O),Cygwin)
|
||||
NO_D_TYPE_IN_DIRENT = YesPlease
|
||||
@@ -884,9 +887,10 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||
USE_NED_ALLOCATOR = YesPlease
|
||||
UNRELIABLE_FSTAT = UnfortunatelyYes
|
||||
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
|
||||
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
|
||||
NO_REGEX = YesPlease
|
||||
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
|
||||
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
||||
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o
|
||||
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
|
||||
EXTLIBS += -lws2_32
|
||||
X = .exe
|
||||
ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
|
||||
@@ -1200,6 +1204,10 @@ endif
|
||||
ifdef UNRELIABLE_FSTAT
|
||||
BASIC_CFLAGS += -DUNRELIABLE_FSTAT
|
||||
endif
|
||||
ifdef NO_REGEX
|
||||
COMPAT_CFLAGS += -Icompat/regex
|
||||
COMPAT_OBJS += compat/regex/regex.o
|
||||
endif
|
||||
|
||||
ifdef USE_NED_ALLOCATOR
|
||||
COMPAT_CFLAGS += -DUSE_NED_ALLOCATOR -DOVERRIDE_STRDUP -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR -Icompat/nedmalloc
|
||||
@@ -1464,7 +1472,7 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
|
||||
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
|
||||
|
||||
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
|
||||
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
|
||||
$(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h)
|
||||
builtin-revert.o wt-status.o: wt-status.h
|
||||
|
||||
$(LIB_FILE): $(LIB_OBJS)
|
||||
@@ -1633,15 +1641,15 @@ ifneq (,$X)
|
||||
endif
|
||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||
{ $(RM) "$$execdir/git-add$X" && \
|
||||
{ $(RM) "$$execdir/git$X" && \
|
||||
test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
|
||||
ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \
|
||||
cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \
|
||||
{ for p in $(filter-out git-add$X,$(BUILT_INS)); do \
|
||||
ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \
|
||||
cp "$$bindir/git$X" "$$execdir/git$X"; } && \
|
||||
{ for p in $(BUILT_INS); do \
|
||||
$(RM) "$$execdir/$$p" && \
|
||||
ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \
|
||||
ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
cp "$$execdir/git$X" "$$execdir/$$p" || exit; \
|
||||
done; } && \
|
||||
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
|
||||
|
||||
|
||||
12
abspath.c
12
abspath.c
@@ -41,13 +41,13 @@ const char *make_absolute_path(const char *path)
|
||||
|
||||
if (*buf) {
|
||||
if (!*cwd && !getcwd(cwd, sizeof(cwd)))
|
||||
die ("Could not get current working directory");
|
||||
die_errno ("Could not get current working directory");
|
||||
|
||||
if (chdir(buf))
|
||||
die ("Could not switch to '%s'", buf);
|
||||
die_errno ("Could not switch to '%s'", buf);
|
||||
}
|
||||
if (!getcwd(buf, PATH_MAX))
|
||||
die ("Could not get current working directory");
|
||||
die_errno ("Could not get current working directory");
|
||||
|
||||
if (last_elem) {
|
||||
int len = strlen(buf);
|
||||
@@ -63,7 +63,7 @@ const char *make_absolute_path(const char *path)
|
||||
if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
|
||||
len = readlink(buf, next_buf, PATH_MAX);
|
||||
if (len < 0)
|
||||
die ("Invalid symlink: %s", buf);
|
||||
die_errno ("Invalid symlink '%s'", buf);
|
||||
if (PATH_MAX <= len)
|
||||
die("symbolic link too long: %s", buf);
|
||||
next_buf[len] = '\0';
|
||||
@@ -75,7 +75,7 @@ const char *make_absolute_path(const char *path)
|
||||
}
|
||||
|
||||
if (*cwd && chdir(cwd))
|
||||
die ("Could not change back to '%s'", cwd);
|
||||
die_errno ("Could not change back to '%s'", cwd);
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ const char *make_nonrelative_path(const char *path)
|
||||
} else {
|
||||
const char *cwd = get_pwd_cwd();
|
||||
if (!cwd)
|
||||
die("Cannot determine the current working directory");
|
||||
die_errno("Cannot determine the current working directory");
|
||||
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
|
||||
die("Too long path: %.*s", 60, path);
|
||||
}
|
||||
|
||||
2
attr.c
2
attr.c
@@ -555,6 +555,8 @@ static void prepare_attr_stack(const char *path, int dirlen)
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&pathbuf);
|
||||
|
||||
/*
|
||||
* Finally push the "info" one at the top of the stack.
|
||||
*/
|
||||
|
||||
55
bisect.c
55
bisect.c
@@ -461,7 +461,7 @@ static void read_bisect_paths(struct argv_array *array)
|
||||
FILE *fp = fopen(filename, "r");
|
||||
|
||||
if (!fp)
|
||||
die("Could not open file '%s': %s", filename, strerror(errno));
|
||||
die_errno("Could not open file '%s'", filename);
|
||||
|
||||
while (strbuf_getline(&str, fp, '\n') != EOF) {
|
||||
char *quoted;
|
||||
@@ -585,16 +585,49 @@ struct commit_list *filter_skipped(struct commit_list *list,
|
||||
return filtered;
|
||||
}
|
||||
|
||||
static struct commit_list *apply_skip_ratio(struct commit_list *list,
|
||||
int count,
|
||||
int skip_num, int skip_denom)
|
||||
#define PRN_MODULO 32768
|
||||
|
||||
/*
|
||||
* This is a pseudo random number generator based on "man 3 rand".
|
||||
* It is not used properly because the seed is the argument and it
|
||||
* is increased by one between each call, but that should not matter
|
||||
* for this application.
|
||||
*/
|
||||
int get_prn(int count) {
|
||||
count = count * 1103515245 + 12345;
|
||||
return ((unsigned)(count/65536) % PRN_MODULO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom integer square root from
|
||||
* http://en.wikipedia.org/wiki/Integer_square_root
|
||||
*/
|
||||
static int sqrti(int val)
|
||||
{
|
||||
float d, x = val;
|
||||
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
float y = (x + (float)val / x) / 2;
|
||||
d = (y > x) ? y - x : x - y;
|
||||
x = y;
|
||||
} while (d >= 0.5);
|
||||
|
||||
return (int)x;
|
||||
}
|
||||
|
||||
static struct commit_list *skip_away(struct commit_list *list, int count)
|
||||
{
|
||||
int index, i;
|
||||
struct commit_list *cur, *previous;
|
||||
int prn, index, i;
|
||||
|
||||
prn = get_prn(count);
|
||||
index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO);
|
||||
|
||||
cur = list;
|
||||
previous = NULL;
|
||||
index = count * skip_num / skip_denom;
|
||||
|
||||
for (i = 0; cur; cur = cur->next, i++) {
|
||||
if (i == index) {
|
||||
@@ -614,7 +647,6 @@ static struct commit_list *managed_skipped(struct commit_list *list,
|
||||
struct commit_list **tried)
|
||||
{
|
||||
int count, skipped_first;
|
||||
int skip_num, skip_denom;
|
||||
|
||||
*tried = NULL;
|
||||
|
||||
@@ -626,11 +658,7 @@ static struct commit_list *managed_skipped(struct commit_list *list,
|
||||
if (!skipped_first)
|
||||
return list;
|
||||
|
||||
/* Use alternatively 1/5, 2/5 and 3/5 as skip ratio. */
|
||||
skip_num = count % 3 + 1;
|
||||
skip_denom = 5;
|
||||
|
||||
return apply_skip_ratio(list, count, skip_num, skip_denom);
|
||||
return skip_away(list, count);
|
||||
}
|
||||
|
||||
static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
|
||||
@@ -712,8 +740,7 @@ static void mark_expected_rev(char *bisect_rev_hex)
|
||||
int fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
|
||||
if (fd < 0)
|
||||
die("could not create file '%s': %s",
|
||||
filename, strerror(errno));
|
||||
die_errno("could not create file '%s'", filename);
|
||||
|
||||
bisect_rev_hex[len] = '\n';
|
||||
write_or_die(fd, bisect_rev_hex, len + 1);
|
||||
|
||||
4
branch.c
4
branch.c
@@ -172,7 +172,7 @@ void create_branch(const char *head,
|
||||
|
||||
lock = lock_any_ref_for_update(ref.buf, NULL, 0);
|
||||
if (!lock)
|
||||
die("Failed to lock ref for update: %s.", strerror(errno));
|
||||
die_errno("Failed to lock ref for update");
|
||||
|
||||
if (reflog)
|
||||
log_all_ref_updates = 1;
|
||||
@@ -188,7 +188,7 @@ void create_branch(const char *head,
|
||||
setup_tracking(name, real_ref, track);
|
||||
|
||||
if (write_ref_sha1(lock, sha1, msg) < 0)
|
||||
die("Failed to write ref: %s.", strerror(errno));
|
||||
die_errno("Failed to write ref");
|
||||
|
||||
strbuf_release(&ref);
|
||||
free(real_ref);
|
||||
|
||||
@@ -220,7 +220,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
launch_editor(file, NULL, NULL);
|
||||
|
||||
if (stat(file, &st))
|
||||
die("Could not stat '%s'", file);
|
||||
die_errno("Could not stat '%s'", file);
|
||||
if (!st.st_size)
|
||||
die("Empty patch. Aborted.");
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,
|
||||
static void read_patch_file(struct strbuf *sb, int fd)
|
||||
{
|
||||
if (strbuf_read(sb, fd, 0) < 0)
|
||||
die("git apply: read returned %s", strerror(errno));
|
||||
die_errno("git apply: failed to read");
|
||||
|
||||
/*
|
||||
* Make sure that we have some slop in the buffer
|
||||
@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
|
||||
} else {
|
||||
if (!cached) {
|
||||
if (lstat(path, &st) < 0)
|
||||
die("unable to stat newly created file %s",
|
||||
path);
|
||||
die_errno("unable to stat newly created file '%s'",
|
||||
path);
|
||||
fill_stat_cache_info(ce, &st);
|
||||
}
|
||||
if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
|
||||
@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
|
||||
strbuf_release(&nbuf);
|
||||
|
||||
if (close(fd) < 0)
|
||||
die("closing file %s: %s", path, strerror(errno));
|
||||
die_errno("closing file '%s'", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
|
||||
++nr;
|
||||
}
|
||||
}
|
||||
die("unable to write file %s mode %o", path, mode);
|
||||
die_errno("unable to write file '%s' mode %o", path, mode);
|
||||
}
|
||||
|
||||
static void create_file(struct patch *patch)
|
||||
@@ -3356,7 +3356,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
|
||||
fd = open(arg, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die("can't open patch '%s': %s", arg, strerror(errno));
|
||||
die_errno("can't open patch '%s'", arg);
|
||||
read_stdin = 0;
|
||||
set_default_whitespace_mode(whitespace_option);
|
||||
errs |= apply_patch(fd, arg, options);
|
||||
|
||||
@@ -13,10 +13,10 @@ static void create_output_file(const char *output_file)
|
||||
{
|
||||
int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
||||
if (output_fd < 0)
|
||||
die("could not create archive file: %s ", output_file);
|
||||
die_errno("could not create archive file '%s'", output_file);
|
||||
if (output_fd != 1) {
|
||||
if (dup2(output_fd, 1) < 0)
|
||||
die("could not redirect output");
|
||||
die_errno("could not redirect output");
|
||||
else
|
||||
close(output_fd);
|
||||
}
|
||||
|
||||
@@ -2008,23 +2008,23 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
|
||||
|
||||
if (contents_from) {
|
||||
if (stat(contents_from, &st) < 0)
|
||||
die("Cannot stat %s", contents_from);
|
||||
die_errno("Cannot stat '%s'", contents_from);
|
||||
read_from = contents_from;
|
||||
}
|
||||
else {
|
||||
if (lstat(path, &st) < 0)
|
||||
die("Cannot lstat %s", path);
|
||||
die_errno("Cannot lstat '%s'", path);
|
||||
read_from = path;
|
||||
}
|
||||
mode = canon_mode(st.st_mode);
|
||||
switch (st.st_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
|
||||
die("cannot open or read %s", read_from);
|
||||
die_errno("cannot open or read '%s'", read_from);
|
||||
break;
|
||||
case S_IFLNK:
|
||||
if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
|
||||
die("cannot readlink %s", read_from);
|
||||
die_errno("cannot readlink '%s'", read_from);
|
||||
break;
|
||||
default:
|
||||
die("unsupported file type %s", read_from);
|
||||
@@ -2035,7 +2035,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
|
||||
contents_from = "standard input";
|
||||
mode = 0;
|
||||
if (strbuf_read(&buf, 0, 0) < 0)
|
||||
die("read error %s from stdin", strerror(errno));
|
||||
die_errno("failed to read from stdin");
|
||||
}
|
||||
convert_to_git(path, buf.buf, buf.len, &buf, 0);
|
||||
origin->file.ptr = buf.buf;
|
||||
@@ -2261,8 +2261,7 @@ parse_done:
|
||||
argc = parse_options_end(&ctx);
|
||||
|
||||
if (revs_file && read_ancestry(revs_file))
|
||||
die("reading graft file %s failed: %s",
|
||||
revs_file, strerror(errno));
|
||||
die_errno("reading graft file '%s' failed", revs_file);
|
||||
|
||||
if (cmd_is_annotate) {
|
||||
output_option |= OUTPUT_ANNOTATE_COMPAT;
|
||||
@@ -2350,7 +2349,7 @@ parse_done:
|
||||
|
||||
setup_work_tree();
|
||||
if (!has_string_in_work_tree(path))
|
||||
die("cannot stat path %s: %s", path, strerror(errno));
|
||||
die_errno("cannot stat path '%s'", path);
|
||||
}
|
||||
|
||||
setup_revisions(argc, argv, &revs, NULL);
|
||||
|
||||
@@ -220,13 +220,13 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
|
||||
|
||||
dir = opendir(src->buf);
|
||||
if (!dir)
|
||||
die("failed to open %s", src->buf);
|
||||
die_errno("failed to open '%s'", src->buf);
|
||||
|
||||
if (mkdir(dest->buf, 0777)) {
|
||||
if (errno != EEXIST)
|
||||
die("failed to create directory %s", dest->buf);
|
||||
die_errno("failed to create directory '%s'", dest->buf);
|
||||
else if (stat(dest->buf, &buf))
|
||||
die("failed to stat %s", dest->buf);
|
||||
die_errno("failed to stat '%s'", dest->buf);
|
||||
else if (!S_ISDIR(buf.st_mode))
|
||||
die("%s exists and is not a directory", dest->buf);
|
||||
}
|
||||
@@ -252,17 +252,16 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
|
||||
}
|
||||
|
||||
if (unlink(dest->buf) && errno != ENOENT)
|
||||
die("failed to unlink %s: %s",
|
||||
dest->buf, strerror(errno));
|
||||
die_errno("failed to unlink '%s'", dest->buf);
|
||||
if (!option_no_hardlinks) {
|
||||
if (!link(src->buf, dest->buf))
|
||||
continue;
|
||||
if (option_local)
|
||||
die("failed to create link %s", dest->buf);
|
||||
die_errno("failed to create link '%s'", dest->buf);
|
||||
option_no_hardlinks = 1;
|
||||
}
|
||||
if (copy_file(dest->buf, src->buf, 0666))
|
||||
die("failed to copy file to %s", dest->buf);
|
||||
die_errno("failed to copy file to '%s'", dest->buf);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
@@ -420,11 +419,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
if (!option_bare) {
|
||||
junk_work_tree = work_tree;
|
||||
if (safe_create_leading_directories_const(work_tree) < 0)
|
||||
die("could not create leading directories of '%s': %s",
|
||||
work_tree, strerror(errno));
|
||||
die_errno("could not create leading directories of '%s'",
|
||||
work_tree);
|
||||
if (!dest_exists && mkdir(work_tree, 0755))
|
||||
die("could not create work tree dir '%s': %s.",
|
||||
work_tree, strerror(errno));
|
||||
die_errno("could not create work tree dir '%s'.",
|
||||
work_tree);
|
||||
set_git_work_tree(work_tree);
|
||||
}
|
||||
junk_git_dir = git_dir;
|
||||
|
||||
@@ -124,7 +124,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
if (strbuf_read(&buffer, 0, 0) < 0)
|
||||
die("git commit-tree: read returned %s", strerror(errno));
|
||||
die_errno("git commit-tree: failed to read");
|
||||
|
||||
if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
|
||||
printf("%s\n", sha1_to_hex(commit_sha1));
|
||||
|
||||
@@ -434,12 +434,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
if (isatty(0))
|
||||
fprintf(stderr, "(reading log message from standard input)\n");
|
||||
if (strbuf_read(&sb, 0, 0) < 0)
|
||||
die("could not read log from standard input");
|
||||
die_errno("could not read log from standard input");
|
||||
hook_arg1 = "message";
|
||||
} else if (logfile) {
|
||||
if (strbuf_read_file(&sb, logfile, 0) < 0)
|
||||
die("could not read log file '%s': %s",
|
||||
logfile, strerror(errno));
|
||||
die_errno("could not read log file '%s'",
|
||||
logfile);
|
||||
hook_arg1 = "message";
|
||||
} else if (use_message) {
|
||||
buffer = strstr(use_message_buffer, "\n\n");
|
||||
@@ -450,16 +450,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
hook_arg2 = use_message;
|
||||
} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
|
||||
die("could not read MERGE_MSG: %s", strerror(errno));
|
||||
die_errno("could not read MERGE_MSG");
|
||||
hook_arg1 = "merge";
|
||||
} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
|
||||
die("could not read SQUASH_MSG: %s", strerror(errno));
|
||||
die_errno("could not read SQUASH_MSG");
|
||||
hook_arg1 = "squash";
|
||||
} else if (template_file && !stat(template_file, &statbuf)) {
|
||||
if (strbuf_read_file(&sb, template_file, 0) < 0)
|
||||
die("could not read %s: %s",
|
||||
template_file, strerror(errno));
|
||||
die_errno("could not read '%s'", template_file);
|
||||
hook_arg1 = "template";
|
||||
}
|
||||
|
||||
@@ -472,8 +471,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
|
||||
fp = fopen(git_path(commit_editmsg), "w");
|
||||
if (fp == NULL)
|
||||
die("could not open %s: %s",
|
||||
git_path(commit_editmsg), strerror(errno));
|
||||
die_errno("could not open '%s'", git_path(commit_editmsg));
|
||||
|
||||
if (cleanup_mode != CLEANUP_NONE)
|
||||
stripspace(&sb, 0);
|
||||
@@ -497,7 +495,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
}
|
||||
|
||||
if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
|
||||
die("could not write commit template: %s", strerror(errno));
|
||||
die_errno("could not write commit template");
|
||||
|
||||
strbuf_release(&sb);
|
||||
|
||||
@@ -940,8 +938,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
|
||||
fp = fopen(git_path("MERGE_HEAD"), "r");
|
||||
if (fp == NULL)
|
||||
die("could not open %s for reading: %s",
|
||||
git_path("MERGE_HEAD"), strerror(errno));
|
||||
die_errno("could not open '%s' for reading",
|
||||
git_path("MERGE_HEAD"));
|
||||
while (strbuf_getline(&m, fp, '\n') != EOF) {
|
||||
unsigned char sha1[20];
|
||||
if (get_sha1_hex(m.buf, sha1) < 0)
|
||||
@@ -952,8 +950,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
strbuf_release(&m);
|
||||
if (!stat(git_path("MERGE_MODE"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
|
||||
die("could not read MERGE_MODE: %s",
|
||||
strerror(errno));
|
||||
die_errno("could not read MERGE_MODE");
|
||||
if (!strcmp(sb.buf, "no-ff"))
|
||||
allow_fast_forward = 0;
|
||||
}
|
||||
@@ -967,8 +964,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
/* Finally, get the commit message */
|
||||
strbuf_reset(&sb);
|
||||
if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
|
||||
int saved_errno = errno;
|
||||
rollback_index_files();
|
||||
die("could not read commit message");
|
||||
die("could not read commit message: %s", strerror(saved_errno));
|
||||
}
|
||||
|
||||
/* Truncate the message just before the diff, if any. */
|
||||
|
||||
@@ -383,8 +383,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix)
|
||||
check_argc(argc, 0, 0);
|
||||
if (git_config(show_all_config, NULL) < 0) {
|
||||
if (config_exclusive_filename)
|
||||
die("unable to read config file %s: %s",
|
||||
config_exclusive_filename, strerror(errno));
|
||||
die_errno("unable to read config file '%s'",
|
||||
config_exclusive_filename);
|
||||
else
|
||||
die("error processing config file(s)");
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
|
||||
usage(builtin_diff_usage);
|
||||
|
||||
if (lstat(path, &st))
|
||||
die("'%s': %s", path, strerror(errno));
|
||||
die_errno("failed to stat '%s'", path);
|
||||
if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
|
||||
die("'%s': not a regular file or symlink", path);
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static void handle_object(const unsigned char *sha1)
|
||||
|
||||
printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
|
||||
if (size && fwrite(buf, size, 1, stdout) != 1)
|
||||
die ("Could not write blob %s", sha1_to_hex(sha1));
|
||||
die_errno ("Could not write blob '%s'", sha1_to_hex(sha1));
|
||||
printf("\n");
|
||||
|
||||
show_progress();
|
||||
@@ -451,7 +451,7 @@ static void import_marks(char *input_file)
|
||||
char line[512];
|
||||
FILE *f = fopen(input_file, "r");
|
||||
if (!f)
|
||||
die("cannot read %s: %s", input_file, strerror(errno));
|
||||
die_errno("cannot read '%s'", input_file);
|
||||
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
uint32_t mark;
|
||||
|
||||
@@ -8,7 +8,7 @@ static char *get_stdin(void)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
if (strbuf_read(&buf, 0, 1024) < 0) {
|
||||
die("error reading standard input: %s", strerror(errno));
|
||||
die_errno("error reading standard input");
|
||||
}
|
||||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
@@ -368,12 +368,11 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
|
||||
if (inpath && strcmp(inpath, "-")) {
|
||||
in = fopen(inpath, "r");
|
||||
if (!in)
|
||||
die("cannot open %s", inpath);
|
||||
die_errno("cannot open '%s'", inpath);
|
||||
}
|
||||
|
||||
if (strbuf_read(&input, fileno(in), 0) < 0)
|
||||
die("could not read input file %s", strerror(errno));
|
||||
|
||||
die_errno("could not read input file");
|
||||
ret = fmt_merge_msg(merge_summary, &input, &output);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -217,7 +217,7 @@ static void check_unreachable_object(struct object *obj)
|
||||
return;
|
||||
}
|
||||
if (!(f = fopen(filename, "w")))
|
||||
die("Could not open %s", filename);
|
||||
die_errno("Could not open '%s'", filename);
|
||||
if (obj->type == OBJ_BLOB) {
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
@@ -225,15 +225,15 @@ static void check_unreachable_object(struct object *obj)
|
||||
&type, &size);
|
||||
if (buf) {
|
||||
if (fwrite(buf, size, 1, f) != 1)
|
||||
die("Could not write %s: %s",
|
||||
filename, strerror(errno));
|
||||
die_errno("Could not write '%s'",
|
||||
filename);
|
||||
free(buf);
|
||||
}
|
||||
} else
|
||||
fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
|
||||
if (fclose(f))
|
||||
die("Could not finish %s: %s",
|
||||
filename, strerror(errno));
|
||||
die_errno("Could not finish '%s'",
|
||||
filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "tree-walk.h"
|
||||
#include "builtin.h"
|
||||
#include "parse-options.h"
|
||||
#include "userdiff.h"
|
||||
#include "grep.h"
|
||||
|
||||
#ifndef NO_EXTERNAL_GREP
|
||||
@@ -30,6 +31,12 @@ static int grep_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
struct grep_opt *opt = cb;
|
||||
|
||||
switch (userdiff_config(var, value)) {
|
||||
case 0: break;
|
||||
case -1: return -1;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "color.grep")) {
|
||||
opt->color = git_config_colorbool(var, value, -1);
|
||||
return 0;
|
||||
@@ -278,6 +285,17 @@ static int flush_grep(struct grep_opt *opt,
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
if (opt->pre_context || opt->post_context) {
|
||||
/*
|
||||
* grep handles hunk marks between files, but we need to
|
||||
* do that ourselves between multiple calls.
|
||||
*/
|
||||
if (opt->show_hunk_mark)
|
||||
write_or_die(1, "--\n", 3);
|
||||
else
|
||||
opt->show_hunk_mark = 1;
|
||||
}
|
||||
|
||||
status = exec_grep(argc, argv);
|
||||
|
||||
if (kept_0) {
|
||||
@@ -594,7 +612,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
|
||||
|
||||
patterns = fopen(arg, "r");
|
||||
if (!patterns)
|
||||
die("'%s': %s", arg, strerror(errno));
|
||||
die_errno("cannot open '%s'", arg);
|
||||
while (strbuf_getline(&sb, patterns, '\n') == 0) {
|
||||
/* ignore empty line like grep does */
|
||||
if (sb.len == 0)
|
||||
@@ -710,6 +728,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||
"show <n> context lines after matches"),
|
||||
OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
|
||||
context_callback),
|
||||
OPT_BOOLEAN('p', "show-function", &opt.funcname,
|
||||
"show a line with the function name before matches"),
|
||||
OPT_GROUP(""),
|
||||
OPT_CALLBACK('f', NULL, &opt, "file",
|
||||
"read patterns from file", file_callback),
|
||||
@@ -778,7 +798,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (opt.color && !opt.color_external)
|
||||
if ((opt.color && !opt.color_external) || opt.funcname)
|
||||
external_grep_allowed = 0;
|
||||
if (!opt.pattern_list)
|
||||
die("no pattern given.");
|
||||
|
||||
@@ -61,20 +61,20 @@ static void copy_templates_1(char *path, int baselen,
|
||||
memcpy(template + template_baselen, de->d_name, namelen+1);
|
||||
if (lstat(path, &st_git)) {
|
||||
if (errno != ENOENT)
|
||||
die("cannot stat %s", path);
|
||||
die_errno("cannot stat '%s'", path);
|
||||
}
|
||||
else
|
||||
exists = 1;
|
||||
|
||||
if (lstat(template, &st_template))
|
||||
die("cannot stat template %s", template);
|
||||
die_errno("cannot stat template '%s'", template);
|
||||
|
||||
if (S_ISDIR(st_template.st_mode)) {
|
||||
DIR *subdir = opendir(template);
|
||||
int baselen_sub = baselen + namelen;
|
||||
int template_baselen_sub = template_baselen + namelen;
|
||||
if (!subdir)
|
||||
die("cannot opendir %s", template);
|
||||
die_errno("cannot opendir '%s'", template);
|
||||
path[baselen_sub++] =
|
||||
template[template_baselen_sub++] = '/';
|
||||
path[baselen_sub] =
|
||||
@@ -91,16 +91,17 @@ static void copy_templates_1(char *path, int baselen,
|
||||
int len;
|
||||
len = readlink(template, lnk, sizeof(lnk));
|
||||
if (len < 0)
|
||||
die("cannot readlink %s", template);
|
||||
die_errno("cannot readlink '%s'", template);
|
||||
if (sizeof(lnk) <= len)
|
||||
die("insanely long symlink %s", template);
|
||||
lnk[len] = 0;
|
||||
if (symlink(lnk, path))
|
||||
die("cannot symlink %s %s", lnk, path);
|
||||
die_errno("cannot symlink '%s' '%s'", lnk, path);
|
||||
}
|
||||
else if (S_ISREG(st_template.st_mode)) {
|
||||
if (copy_file(path, template, st_template.st_mode))
|
||||
die("cannot copy %s to %s", template, path);
|
||||
die_errno("cannot copy '%s' to '%s'", template,
|
||||
path);
|
||||
}
|
||||
else
|
||||
error("ignoring template %s", template);
|
||||
@@ -350,7 +351,7 @@ static int guess_repository_type(const char *git_dir)
|
||||
if (!strcmp(".", git_dir))
|
||||
return 1;
|
||||
if (!getcwd(cwd, sizeof(cwd)))
|
||||
die("cannot tell cwd");
|
||||
die_errno("cannot tell cwd");
|
||||
if (!strcmp(git_dir, cwd))
|
||||
return 1;
|
||||
/*
|
||||
@@ -440,11 +441,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
if (!git_work_tree_cfg) {
|
||||
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
|
||||
if (!getcwd(git_work_tree_cfg, PATH_MAX))
|
||||
die ("Cannot access current working directory.");
|
||||
die_errno ("Cannot access current working directory");
|
||||
}
|
||||
if (access(get_git_work_tree(), X_OK))
|
||||
die ("Cannot access work tree '%s'",
|
||||
get_git_work_tree());
|
||||
die_errno ("Cannot access work tree '%s'",
|
||||
get_git_work_tree());
|
||||
}
|
||||
|
||||
set_git_dir(make_absolute_path(git_dir));
|
||||
|
||||
@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
if (use_stdout)
|
||||
die("standard output, or directory, which one?");
|
||||
if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
|
||||
die("Could not create directory %s",
|
||||
output_directory);
|
||||
die_errno("Could not create directory '%s'",
|
||||
output_directory);
|
||||
}
|
||||
|
||||
if (rev.pending.nr == 1) {
|
||||
|
||||
@@ -81,7 +81,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
|
||||
|
||||
fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||
if (fd < 0)
|
||||
die("cannot open output file %s", name);
|
||||
die_errno("cannot open output file '%s'", name);
|
||||
output = fdopen(fd, "w");
|
||||
|
||||
/* Copy it out, while searching for a line that begins with
|
||||
@@ -91,7 +91,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
|
||||
int is_partial = len && buf[len-1] != '\n';
|
||||
|
||||
if (fwrite(buf, 1, len, output) != len)
|
||||
die("cannot write output");
|
||||
die_errno("cannot write output");
|
||||
|
||||
len = read_line_with_nul(buf, sizeof(buf), mbox);
|
||||
if (len == 0) {
|
||||
@@ -99,7 +99,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
die("cannot read mbox");
|
||||
die_errno("cannot read mbox");
|
||||
}
|
||||
if (!is_partial && !is_bare && is_from_line(buf, len))
|
||||
break; /* done with one message */
|
||||
|
||||
@@ -268,7 +268,7 @@ static void squash_message(void)
|
||||
printf("Squash commit -- not updating HEAD\n");
|
||||
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die("Could not write to %s", git_path("SQUASH_MSG"));
|
||||
die_errno("Could not write to '%s'", git_path("SQUASH_MSG"));
|
||||
|
||||
init_revisions(&rev, NULL);
|
||||
rev.ignore_merges = 1;
|
||||
@@ -294,9 +294,9 @@ static void squash_message(void)
|
||||
NULL, NULL, rev.date_mode, 0);
|
||||
}
|
||||
if (write(fd, out.buf, out.len) < 0)
|
||||
die("Writing SQUASH_MSG: %s", strerror(errno));
|
||||
die_errno("Writing SQUASH_MSG");
|
||||
if (close(fd))
|
||||
die("Finishing SQUASH_MSG: %s", strerror(errno));
|
||||
die_errno("Finishing SQUASH_MSG");
|
||||
strbuf_release(&out);
|
||||
}
|
||||
|
||||
@@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct strbuf *msg)
|
||||
|
||||
fp = fopen(git_path("FETCH_HEAD"), "r");
|
||||
if (!fp)
|
||||
die("could not open %s for reading: %s",
|
||||
git_path("FETCH_HEAD"), strerror(errno));
|
||||
die_errno("could not open '%s' for reading",
|
||||
git_path("FETCH_HEAD"));
|
||||
strbuf_getline(&line, fp, '\n');
|
||||
fclose(fp);
|
||||
ptr = strstr(line.buf, "\tnot-for-merge\t");
|
||||
@@ -764,7 +764,8 @@ static int suggest_conflicts(void)
|
||||
|
||||
fp = fopen(git_path("MERGE_MSG"), "a");
|
||||
if (!fp)
|
||||
die("Could not open %s for writing", git_path("MERGE_MSG"));
|
||||
die_errno("Could not open '%s' for writing",
|
||||
git_path("MERGE_MSG"));
|
||||
fprintf(fp, "\nConflicts:\n");
|
||||
for (pos = 0; pos < active_nr; pos++) {
|
||||
struct cache_entry *ce = active_cache[pos];
|
||||
@@ -1189,27 +1190,29 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
sha1_to_hex(j->item->object.sha1));
|
||||
fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die("Could open %s for writing",
|
||||
git_path("MERGE_HEAD"));
|
||||
die_errno("Could not open '%s' for writing",
|
||||
git_path("MERGE_HEAD"));
|
||||
if (write_in_full(fd, buf.buf, buf.len) != buf.len)
|
||||
die("Could not write to %s", git_path("MERGE_HEAD"));
|
||||
die_errno("Could not write to '%s'", git_path("MERGE_HEAD"));
|
||||
close(fd);
|
||||
strbuf_addch(&merge_msg, '\n');
|
||||
fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die("Could open %s for writing", git_path("MERGE_MSG"));
|
||||
die_errno("Could not open '%s' for writing",
|
||||
git_path("MERGE_MSG"));
|
||||
if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
|
||||
merge_msg.len)
|
||||
die("Could not write to %s", git_path("MERGE_MSG"));
|
||||
die_errno("Could not write to '%s'", git_path("MERGE_MSG"));
|
||||
close(fd);
|
||||
fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
die("Could open %s for writing", git_path("MERGE_MODE"));
|
||||
die_errno("Could not open '%s' for writing",
|
||||
git_path("MERGE_MODE"));
|
||||
strbuf_reset(&buf);
|
||||
if (!allow_fast_forward)
|
||||
strbuf_addf(&buf, "no-ff");
|
||||
if (write_in_full(fd, buf.buf, buf.len) != buf.len)
|
||||
die("Could not write to %s", git_path("MERGE_MODE"));
|
||||
die_errno("Could not write to '%s'", git_path("MERGE_MODE"));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
12
builtin-mv.c
12
builtin-mv.c
@@ -24,14 +24,10 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec,
|
||||
result[count] = NULL;
|
||||
for (i = 0; i < count; i++) {
|
||||
int length = strlen(result[i]);
|
||||
if (length > 0 && result[i][length - 1] == '/') {
|
||||
if (length > 0 && is_dir_sep(result[i][length - 1]))
|
||||
result[i] = xmemdupz(result[i], length - 1);
|
||||
}
|
||||
if (base_name) {
|
||||
const char *last_slash = strrchr(result[i], '/');
|
||||
if (last_slash)
|
||||
result[i] = last_slash + 1;
|
||||
}
|
||||
if (base_name)
|
||||
result[i] = basename((char *)result[i]);
|
||||
}
|
||||
return get_pathspec(prefix, result);
|
||||
}
|
||||
@@ -209,7 +205,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
printf("Renaming %s to %s\n", src, dst);
|
||||
if (!show_only && mode != INDEX &&
|
||||
rename(src, dst) < 0 && !ignore_errors)
|
||||
die ("renaming %s failed: %s", src, strerror(errno));
|
||||
die_errno ("renaming '%s' failed", src);
|
||||
|
||||
if (mode == WORKING_DIRECTORY)
|
||||
continue;
|
||||
|
||||
@@ -536,11 +536,9 @@ static void write_pack_file(void)
|
||||
base_name, sha1_to_hex(sha1));
|
||||
free_pack_by_name(tmpname);
|
||||
if (adjust_perm(pack_tmp_name, mode))
|
||||
die("unable to make temporary pack file readable: %s",
|
||||
strerror(errno));
|
||||
die_errno("unable to make temporary pack file readable");
|
||||
if (rename(pack_tmp_name, tmpname))
|
||||
die("unable to rename temporary pack file: %s",
|
||||
strerror(errno));
|
||||
die_errno("unable to rename temporary pack file");
|
||||
|
||||
/*
|
||||
* Packs are runtime accessed in their mtime
|
||||
@@ -566,11 +564,9 @@ static void write_pack_file(void)
|
||||
snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
|
||||
base_name, sha1_to_hex(sha1));
|
||||
if (adjust_perm(idx_tmp_name, mode))
|
||||
die("unable to make temporary index file readable: %s",
|
||||
strerror(errno));
|
||||
die_errno("unable to make temporary index file readable");
|
||||
if (rename(idx_tmp_name, tmpname))
|
||||
die("unable to rename temporary index file: %s",
|
||||
strerror(errno));
|
||||
die_errno("unable to rename temporary index file");
|
||||
|
||||
free(idx_tmp_name);
|
||||
free(pack_tmp_name);
|
||||
@@ -1879,7 +1875,7 @@ static void read_object_list_from_stdin(void)
|
||||
if (!ferror(stdin))
|
||||
die("fgets returned NULL, not EOF, not error!");
|
||||
if (errno != EINTR)
|
||||
die("fgets: %s", strerror(errno));
|
||||
die_errno("fgets");
|
||||
clearerr(stdin);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "parse-options.h"
|
||||
|
||||
static const char * const push_usage[] = {
|
||||
"git push [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]",
|
||||
"git push [--all | --mirror] [--dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]",
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -200,6 +200,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
||||
(TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
|
||||
OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
|
||||
OPT_BIT( 0 , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
|
||||
OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
|
||||
OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
|
||||
OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
|
||||
OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
|
||||
|
||||
@@ -123,27 +123,27 @@ static struct command *commands;
|
||||
static const char pre_receive_hook[] = "hooks/pre-receive";
|
||||
static const char post_receive_hook[] = "hooks/post-receive";
|
||||
|
||||
static int hook_status(int code, const char *hook_name)
|
||||
static int run_status(int code, const char *cmd_name)
|
||||
{
|
||||
switch (code) {
|
||||
case 0:
|
||||
return 0;
|
||||
case -ERR_RUN_COMMAND_FORK:
|
||||
return error("hook fork failed");
|
||||
return error("fork of %s failed", cmd_name);
|
||||
case -ERR_RUN_COMMAND_EXEC:
|
||||
return error("hook execute failed");
|
||||
return error("execute of %s failed", cmd_name);
|
||||
case -ERR_RUN_COMMAND_PIPE:
|
||||
return error("hook pipe failed");
|
||||
return error("pipe failed");
|
||||
case -ERR_RUN_COMMAND_WAITPID:
|
||||
return error("waitpid failed");
|
||||
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
|
||||
return error("waitpid is confused");
|
||||
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
|
||||
return error("%s died of signal", hook_name);
|
||||
return error("%s died of signal", cmd_name);
|
||||
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
|
||||
return error("%s died strangely", hook_name);
|
||||
return error("%s died strangely", cmd_name);
|
||||
default:
|
||||
error("%s exited with error code %d", hook_name, -code);
|
||||
error("%s exited with error code %d", cmd_name, -code);
|
||||
return -code;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,7 @@ static int run_receive_hook(const char *hook_name)
|
||||
|
||||
code = start_command(&proc);
|
||||
if (code)
|
||||
return hook_status(code, hook_name);
|
||||
return run_status(code, hook_name);
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!cmd->error_string) {
|
||||
size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
|
||||
@@ -186,7 +186,7 @@ static int run_receive_hook(const char *hook_name)
|
||||
}
|
||||
}
|
||||
close(proc.in);
|
||||
return hook_status(finish_command(&proc), hook_name);
|
||||
return run_status(finish_command(&proc), hook_name);
|
||||
}
|
||||
|
||||
static int run_update_hook(struct command *cmd)
|
||||
@@ -203,7 +203,7 @@ static int run_update_hook(struct command *cmd)
|
||||
argv[3] = sha1_to_hex(cmd->new_sha1);
|
||||
argv[4] = NULL;
|
||||
|
||||
return hook_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
|
||||
return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
|
||||
RUN_COMMAND_STDOUT_TO_STDERR),
|
||||
update_hook);
|
||||
}
|
||||
@@ -394,7 +394,7 @@ static char update_post_hook[] = "hooks/post-update";
|
||||
static void run_update_post_hook(struct command *cmd)
|
||||
{
|
||||
struct command *cmd_p;
|
||||
int argc;
|
||||
int argc, status;
|
||||
const char **argv;
|
||||
|
||||
for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
|
||||
@@ -417,8 +417,9 @@ static void run_update_post_hook(struct command *cmd)
|
||||
argc++;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
|
||||
| RUN_COMMAND_STDOUT_TO_STDERR);
|
||||
status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
|
||||
| RUN_COMMAND_STDOUT_TO_STDERR);
|
||||
run_status(status, update_post_hook);
|
||||
}
|
||||
|
||||
static void execute_commands(const char *unpacker_error)
|
||||
@@ -534,24 +535,10 @@ static const char *unpack(void)
|
||||
unpacker[i++] = hdr_arg;
|
||||
unpacker[i++] = NULL;
|
||||
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
|
||||
switch (code) {
|
||||
case 0:
|
||||
if (!code)
|
||||
return NULL;
|
||||
case -ERR_RUN_COMMAND_FORK:
|
||||
return "unpack fork failed";
|
||||
case -ERR_RUN_COMMAND_EXEC:
|
||||
return "unpack execute failed";
|
||||
case -ERR_RUN_COMMAND_WAITPID:
|
||||
return "waitpid failed";
|
||||
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
|
||||
return "waitpid is confused";
|
||||
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
|
||||
return "unpacker died of signal";
|
||||
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
|
||||
return "unpacker died strangely";
|
||||
default:
|
||||
return "unpacker exited with error code";
|
||||
}
|
||||
run_status(code, unpacker[0]);
|
||||
return "unpack-objects abnormal exit";
|
||||
} else {
|
||||
const char *keeper[7];
|
||||
int s, status, i = 0;
|
||||
@@ -574,8 +561,11 @@ static const char *unpack(void)
|
||||
ip.argv = keeper;
|
||||
ip.out = -1;
|
||||
ip.git_cmd = 1;
|
||||
if (start_command(&ip))
|
||||
status = start_command(&ip);
|
||||
if (status) {
|
||||
run_status(status, keeper[0]);
|
||||
return "index-pack fork failed";
|
||||
}
|
||||
pack_lockfile = index_pack_lockfile(ip.out);
|
||||
close(ip.out);
|
||||
status = finish_command(&ip);
|
||||
@@ -583,6 +573,7 @@ static const char *unpack(void)
|
||||
reprepare_packed_git();
|
||||
return NULL;
|
||||
}
|
||||
run_status(status, keeper[0]);
|
||||
return "index-pack abnormal exit";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ static int get_remote_ref_states(const char *name,
|
||||
read_branches();
|
||||
|
||||
if (query) {
|
||||
transport = transport_get(NULL, states->remote->url_nr > 0 ?
|
||||
transport = transport_get(states->remote, states->remote->url_nr > 0 ?
|
||||
states->remote->url[0] : NULL);
|
||||
remote_refs = transport_get_remote_refs(transport);
|
||||
transport_disconnect(transport);
|
||||
@@ -1276,15 +1276,14 @@ static int update(int argc, const char **argv)
|
||||
static int get_one_entry(struct remote *remote, void *priv)
|
||||
{
|
||||
struct string_list *list = priv;
|
||||
struct strbuf url_buf = STRBUF_INIT;
|
||||
const char **url;
|
||||
int i, url_nr;
|
||||
void **utilp;
|
||||
|
||||
if (remote->url_nr > 0) {
|
||||
utilp = &(string_list_append(remote->name, list)->util);
|
||||
*utilp = xmalloc(strlen(remote->url[0])+strlen(" (fetch)")+1);
|
||||
strcpy((char *) *utilp, remote->url[0]);
|
||||
strcat((char *) *utilp, " (fetch)");
|
||||
strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
|
||||
string_list_append(remote->name, list)->util =
|
||||
strbuf_detach(&url_buf, NULL);
|
||||
} else
|
||||
string_list_append(remote->name, list)->util = NULL;
|
||||
if (remote->pushurl_nr) {
|
||||
@@ -1296,10 +1295,9 @@ static int get_one_entry(struct remote *remote, void *priv)
|
||||
}
|
||||
for (i = 0; i < url_nr; i++)
|
||||
{
|
||||
utilp = &(string_list_append(remote->name, list)->util);
|
||||
*utilp = xmalloc(strlen(url[i])+strlen(" (push)")+1);
|
||||
strcpy((char *) *utilp, url[i]);
|
||||
strcat((char *) *utilp, " (push)");
|
||||
strbuf_addf(&url_buf, "%s (push)", url[i]);
|
||||
string_list_append(remote->name, list)->util =
|
||||
strbuf_detach(&url_buf, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -301,7 +301,7 @@ static const char *skipspaces(const char *s)
|
||||
|
||||
static int cmd_parseopt(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
static int keep_dashdash = 0;
|
||||
static int keep_dashdash = 0, stop_at_non_option = 0;
|
||||
static char const * const parseopt_usage[] = {
|
||||
"git rev-parse --parseopt [options] -- [<args>...]",
|
||||
NULL
|
||||
@@ -309,6 +309,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
|
||||
static struct option parseopt_opts[] = {
|
||||
OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
|
||||
"keep the `--` passed as an arg"),
|
||||
OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option,
|
||||
"stop parsing after the "
|
||||
"first non-option argument"),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
@@ -394,7 +397,8 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
|
||||
ALLOC_GROW(opts, onb + 1, osz);
|
||||
memset(opts + onb, 0, sizeof(opts[onb]));
|
||||
argc = parse_options(argc, argv, prefix, opts, usage,
|
||||
keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0);
|
||||
keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0 |
|
||||
stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0);
|
||||
|
||||
strbuf_addf(&parsed, " --");
|
||||
sq_quote_argv(&parsed, argv, 0);
|
||||
@@ -592,7 +596,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
if (!getcwd(cwd, PATH_MAX))
|
||||
die("unable to get current working directory");
|
||||
die_errno("unable to get current working directory");
|
||||
printf("%s/.git\n", cwd);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)
|
||||
{
|
||||
int len = strlen(string);
|
||||
if (write_in_full(msg_fd, string, len) < 0)
|
||||
die ("Could not write to MERGE_MSG");
|
||||
die_errno ("Could not write to MERGE_MSG");
|
||||
}
|
||||
|
||||
static void add_message_to_msg(const char *message)
|
||||
|
||||
@@ -257,7 +257,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
if (!removed)
|
||||
die("git rm: %s: %s", path, strerror(errno));
|
||||
die_errno("git rm: '%s'", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
|
||||
po.out = fd;
|
||||
po.git_cmd = 1;
|
||||
if (start_command(&po))
|
||||
die("git pack-objects failed (%s)", strerror(errno));
|
||||
die_errno("git pack-objects failed");
|
||||
|
||||
/*
|
||||
* We feed the pack-objects we just spawned with revision
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
#include "object.h"
|
||||
#include "tag.h"
|
||||
#include "string-list.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--dereference] [-s|--hash[=<length>]] [--abbrev[=<length>]] [--tags] [--heads] [--] [pattern*] < ref-list";
|
||||
static const char * const show_ref_usage[] = {
|
||||
"git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--dereference] [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] ",
|
||||
"git show-ref --exclude-existing[=pattern] < ref-list",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int deref_tags = 0, show_head = 0, tags_only = 0, heads_only = 0,
|
||||
found_match = 0, verify = 0, quiet = 0, hash_only = 0, abbrev = 0;
|
||||
static int deref_tags, show_head, tags_only, heads_only, found_match, verify,
|
||||
quiet, hash_only, abbrev, exclude_arg;
|
||||
static const char **pattern;
|
||||
static const char *exclude_existing_arg;
|
||||
|
||||
static void show_one(const char *refname, const unsigned char *sha1)
|
||||
{
|
||||
@@ -150,79 +156,60 @@ static int exclude_existing(const char *match)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hash_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
hash_only = 1;
|
||||
/* Use full length SHA1 if no argument */
|
||||
if (!arg)
|
||||
return 0;
|
||||
return parse_opt_abbrev_cb(opt, arg, unset);
|
||||
}
|
||||
|
||||
static int exclude_existing_callback(const struct option *opt, const char *arg,
|
||||
int unset)
|
||||
{
|
||||
exclude_arg = 1;
|
||||
*(const char **)opt->value = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int help_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct option show_ref_options[] = {
|
||||
OPT_BOOLEAN(0, "tags", &tags_only, "only show tags (can be combined with heads)"),
|
||||
OPT_BOOLEAN(0, "heads", &heads_only, "only show heads (can be combined with tags)"),
|
||||
OPT_BOOLEAN(0, "verify", &verify, "stricter reference checking, "
|
||||
"requires exact ref path"),
|
||||
OPT_BOOLEAN('h', "head", &show_head, "show the HEAD reference"),
|
||||
OPT_BOOLEAN('d', "dereference", &deref_tags,
|
||||
"dereference tags into object IDs"),
|
||||
{ OPTION_CALLBACK, 's', "hash", &abbrev, "n",
|
||||
"only show SHA1 hash using <n> digits",
|
||||
PARSE_OPT_OPTARG, &hash_callback },
|
||||
OPT__ABBREV(&abbrev),
|
||||
OPT__QUIET(&quiet),
|
||||
{ OPTION_CALLBACK, 0, "exclude-existing", &exclude_existing_arg,
|
||||
"pattern", "show refs from stdin that aren't in local repository",
|
||||
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, exclude_existing_callback },
|
||||
{ OPTION_CALLBACK, 0, "help-all", NULL, NULL, "show usage",
|
||||
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
int cmd_show_ref(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i;
|
||||
argc = parse_options(argc, argv, prefix, show_ref_options,
|
||||
show_ref_usage, PARSE_OPT_NO_INTERNAL_HELP);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (*arg != '-') {
|
||||
pattern = argv + i;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(arg, "--")) {
|
||||
pattern = argv + i + 1;
|
||||
if (!*pattern)
|
||||
pattern = NULL;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet")) {
|
||||
quiet = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-h") || !strcmp(arg, "--head")) {
|
||||
show_head = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-d") || !strcmp(arg, "--dereference")) {
|
||||
deref_tags = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-s") || !strcmp(arg, "--hash")) {
|
||||
hash_only = 1;
|
||||
continue;
|
||||
}
|
||||
if (!prefixcmp(arg, "--hash=") ||
|
||||
(!prefixcmp(arg, "--abbrev") &&
|
||||
(arg[8] == '=' || arg[8] == '\0'))) {
|
||||
if (arg[2] != 'h' && !arg[8])
|
||||
/* --abbrev only */
|
||||
abbrev = DEFAULT_ABBREV;
|
||||
else {
|
||||
/* --hash= or --abbrev= */
|
||||
char *end;
|
||||
if (arg[2] == 'h') {
|
||||
hash_only = 1;
|
||||
arg += 7;
|
||||
}
|
||||
else
|
||||
arg += 9;
|
||||
abbrev = strtoul(arg, &end, 10);
|
||||
if (*end || abbrev > 40)
|
||||
usage(show_ref_usage);
|
||||
if (abbrev < MINIMUM_ABBREV)
|
||||
abbrev = MINIMUM_ABBREV;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--verify")) {
|
||||
verify = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--tags")) {
|
||||
tags_only = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--heads")) {
|
||||
heads_only = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--exclude-existing"))
|
||||
return exclude_existing(NULL);
|
||||
if (!prefixcmp(arg, "--exclude-existing="))
|
||||
return exclude_existing(arg + 19);
|
||||
usage(show_ref_usage);
|
||||
}
|
||||
if (exclude_arg)
|
||||
return exclude_existing(exclude_existing_arg);
|
||||
|
||||
pattern = argv;
|
||||
if (!*pattern)
|
||||
pattern = NULL;
|
||||
|
||||
if (verify) {
|
||||
if (!pattern)
|
||||
|
||||
@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
|
||||
strip_comments = 1;
|
||||
|
||||
if (strbuf_read(&buf, 0, 1024) < 0)
|
||||
die("could not read the input");
|
||||
die_errno("could not read the input");
|
||||
|
||||
stripspace(&buf, strip_comments);
|
||||
|
||||
|
||||
@@ -308,8 +308,7 @@ static void create_tag(const unsigned char *object, const char *tag,
|
||||
path = git_pathdup("TAG_EDITMSG");
|
||||
fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
if (fd < 0)
|
||||
die("could not create file '%s': %s",
|
||||
path, strerror(errno));
|
||||
die_errno("could not create file '%s'", path);
|
||||
|
||||
if (!is_null_sha1(prev))
|
||||
write_tag_body(fd, prev);
|
||||
@@ -443,11 +442,11 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
else {
|
||||
if (!strcmp(msgfile, "-")) {
|
||||
if (strbuf_read(&buf, 0, 1024) < 0)
|
||||
die("cannot read %s", msgfile);
|
||||
die_errno("cannot read '%s'", msgfile);
|
||||
} else {
|
||||
if (strbuf_read_file(&buf, msgfile, 1024) < 0)
|
||||
die("could not open or read '%s': %s",
|
||||
msgfile, strerror(errno));
|
||||
die_errno("could not open or read '%s'",
|
||||
msgfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
|
||||
|
||||
n = write_in_full(1, content + 11, 41);
|
||||
if (n < 41)
|
||||
die("git get-tar-commit-id: write error");
|
||||
die_errno("git get-tar-commit-id: write error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ static void *fill(int min)
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
die("early EOF");
|
||||
die("read error on input: %s", strerror(errno));
|
||||
die_errno("read error on input");
|
||||
}
|
||||
len += ret;
|
||||
} while (len < min);
|
||||
|
||||
@@ -746,7 +746,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
||||
|
||||
done = read_in_full(fd, result, len);
|
||||
if (done < 0)
|
||||
die("read error '%s'", elem->path);
|
||||
die_errno("read error '%s'", elem->path);
|
||||
else if (done < len)
|
||||
die("early EOF '%s'", elem->path);
|
||||
|
||||
|
||||
6
commit.c
6
commit.c
@@ -50,7 +50,6 @@ struct commit *lookup_commit(const unsigned char *sha1)
|
||||
|
||||
static unsigned long parse_commit_date(const char *buf, const char *tail)
|
||||
{
|
||||
unsigned long date;
|
||||
const char *dateptr;
|
||||
|
||||
if (buf + 6 >= tail)
|
||||
@@ -73,10 +72,7 @@ static unsigned long parse_commit_date(const char *buf, const char *tail)
|
||||
if (buf >= tail)
|
||||
return 0;
|
||||
/* dateptr < buf && buf[-1] == '\n', so strtoul will stop at buf-1 */
|
||||
date = strtoul(dateptr, NULL, 10);
|
||||
if (date == ULONG_MAX)
|
||||
date = 0;
|
||||
return date;
|
||||
return strtoul(dateptr, NULL, 10);
|
||||
}
|
||||
|
||||
static struct commit_graft **commit_graft;
|
||||
|
||||
@@ -92,6 +92,8 @@ static inline int fcntl(int fd, int cmd, long arg)
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
/* bash cannot reliably detect negative return codes as failure */
|
||||
#define exit(code) exit((code) & 0xff)
|
||||
|
||||
/*
|
||||
* simple adaptors
|
||||
|
||||
@@ -1165,7 +1165,7 @@ _git_log ()
|
||||
$__git_log_shortlog_options
|
||||
$__git_log_gitk_options
|
||||
--root --topo-order --date-order --reverse
|
||||
--follow
|
||||
--follow --full-diff
|
||||
--abbrev-commit --abbrev=
|
||||
--relative-date --date=
|
||||
--pretty= --format= --oneline
|
||||
@@ -1357,11 +1357,12 @@ __git_config_get_set_variables ()
|
||||
c=$((--c))
|
||||
done
|
||||
|
||||
for i in $(git --git-dir="$(__gitdir)" config $config_file --list \
|
||||
2>/dev/null); do
|
||||
case "$i" in
|
||||
*.*)
|
||||
echo "${i/=*/}"
|
||||
git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
|
||||
while read line
|
||||
do
|
||||
case "$line" in
|
||||
*.*=*)
|
||||
echo "${line/=*/}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -1457,7 +1458,7 @@ _git_config ()
|
||||
branch.*.*)
|
||||
local pfx="${cur%.*}."
|
||||
cur="${cur##*.}"
|
||||
__gitcomp "remote merge mergeoptions" "$pfx" "$cur"
|
||||
__gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
|
||||
return
|
||||
;;
|
||||
branch.*)
|
||||
@@ -1504,7 +1505,7 @@ _git_config ()
|
||||
cur="${cur##*.}"
|
||||
__gitcomp "
|
||||
url proxy fetch push mirror skipDefaultUpdate
|
||||
receivepack uploadpack tagopt
|
||||
receivepack uploadpack tagopt pushurl
|
||||
" "$pfx" "$cur"
|
||||
return
|
||||
;;
|
||||
@@ -1522,6 +1523,7 @@ _git_config ()
|
||||
;;
|
||||
esac
|
||||
__gitcomp "
|
||||
add.ignore-errors
|
||||
alias.
|
||||
apply.whitespace
|
||||
branch.autosetupmerge
|
||||
|
||||
@@ -26,7 +26,7 @@ static void flush(struct sha1file *f, void * buf, unsigned int count)
|
||||
}
|
||||
if (!ret)
|
||||
die("sha1 file '%s' write error. Out of diskspace", f->name);
|
||||
die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
|
||||
die_errno("sha1 file '%s' write error", f->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
|
||||
if (flags & CSUM_FSYNC)
|
||||
fsync_or_die(f->fd, f->name);
|
||||
if (close(f->fd))
|
||||
die("%s: sha1 file error on close (%s)",
|
||||
f->name, strerror(errno));
|
||||
die_errno("%s: sha1 file error on close", f->name);
|
||||
fd = 0;
|
||||
} else
|
||||
fd = f->fd;
|
||||
|
||||
71
daemon.c
71
daemon.c
@@ -1,6 +1,8 @@
|
||||
#include "cache.h"
|
||||
#include "pkt-line.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "run-command.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
@@ -343,28 +345,66 @@ static int run_service(char *dir, struct daemon_service *service)
|
||||
return service->fn();
|
||||
}
|
||||
|
||||
static void copy_to_log(int fd)
|
||||
{
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
FILE *fp;
|
||||
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp == NULL) {
|
||||
logerror("fdopen of error channel failed");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
while (strbuf_getline(&line, fp, '\n') != EOF) {
|
||||
logerror("%s", line.buf);
|
||||
strbuf_setlen(&line, 0);
|
||||
}
|
||||
|
||||
strbuf_release(&line);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int run_service_command(const char **argv)
|
||||
{
|
||||
struct child_process cld;
|
||||
|
||||
memset(&cld, 0, sizeof(cld));
|
||||
cld.argv = argv;
|
||||
cld.git_cmd = 1;
|
||||
cld.err = -1;
|
||||
if (start_command(&cld))
|
||||
return -1;
|
||||
|
||||
close(0);
|
||||
close(1);
|
||||
|
||||
copy_to_log(cld.err);
|
||||
|
||||
return finish_command(&cld);
|
||||
}
|
||||
|
||||
static int upload_pack(void)
|
||||
{
|
||||
/* Timeout as string */
|
||||
char timeout_buf[64];
|
||||
const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
|
||||
|
||||
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
|
||||
|
||||
/* git-upload-pack only ever reads stuff, so this is safe */
|
||||
execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
|
||||
return -1;
|
||||
return run_service_command(argv);
|
||||
}
|
||||
|
||||
static int upload_archive(void)
|
||||
{
|
||||
execl_git_cmd("upload-archive", ".", NULL);
|
||||
return -1;
|
||||
static const char *argv[] = { "upload-archive", ".", NULL };
|
||||
return run_service_command(argv);
|
||||
}
|
||||
|
||||
static int receive_pack(void)
|
||||
{
|
||||
execl_git_cmd("receive-pack", ".", NULL);
|
||||
return -1;
|
||||
static const char *argv[] = { "receive-pack", ".", NULL };
|
||||
return run_service_command(argv);
|
||||
}
|
||||
|
||||
static struct daemon_service daemon_service[] = {
|
||||
@@ -862,7 +902,7 @@ static int service_loop(int socknum, int *socklist)
|
||||
case ECONNABORTED:
|
||||
continue;
|
||||
default:
|
||||
die("accept returned %s", strerror(errno));
|
||||
die_errno("accept returned");
|
||||
}
|
||||
}
|
||||
handle(incoming, (struct sockaddr *)&ss, sslen);
|
||||
@@ -878,7 +918,7 @@ static void sanitize_stdfds(void)
|
||||
while (fd != -1 && fd < 2)
|
||||
fd = dup(fd);
|
||||
if (fd == -1)
|
||||
die("open /dev/null or dup failed: %s", strerror(errno));
|
||||
die_errno("open /dev/null or dup failed");
|
||||
if (fd > 2)
|
||||
close(fd);
|
||||
}
|
||||
@@ -889,12 +929,12 @@ static void daemonize(void)
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
die("fork failed: %s", strerror(errno));
|
||||
die_errno("fork failed");
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
if (setsid() == -1)
|
||||
die("setsid failed: %s", strerror(errno));
|
||||
die_errno("setsid failed");
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
@@ -905,9 +945,9 @@ static void store_pid(const char *path)
|
||||
{
|
||||
FILE *f = fopen(path, "w");
|
||||
if (!f)
|
||||
die("cannot open pid file %s: %s", path, strerror(errno));
|
||||
die_errno("cannot open pid file '%s'", path);
|
||||
if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
|
||||
die("failed to write pid file %s: %s", path, strerror(errno));
|
||||
die_errno("failed to write pid file '%s'", path);
|
||||
}
|
||||
|
||||
static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
|
||||
@@ -1107,8 +1147,7 @@ int main(int argc, char **argv)
|
||||
socklen_t slen = sizeof(ss);
|
||||
|
||||
if (!freopen("/dev/null", "w", stderr))
|
||||
die("failed to redirect stderr to /dev/null: %s",
|
||||
strerror(errno));
|
||||
die_errno("failed to redirect stderr to /dev/null");
|
||||
|
||||
if (getpeername(0, peer, &slen))
|
||||
peer = NULL;
|
||||
|
||||
11
diff.c
11
diff.c
@@ -1603,6 +1603,7 @@ static void builtin_diff(const char *name_a,
|
||||
free(mf1.ptr);
|
||||
if (textconv_two)
|
||||
free(mf2.ptr);
|
||||
xdiff_clear_find_func(&xecfg);
|
||||
}
|
||||
|
||||
free_ab_and_return:
|
||||
@@ -1975,14 +1976,14 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
|
||||
fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,
|
||||
strlen(base) + 1);
|
||||
if (fd < 0)
|
||||
die("unable to create temp-file: %s", strerror(errno));
|
||||
die_errno("unable to create temp-file");
|
||||
if (convert_to_working_tree(path,
|
||||
(const char *)blob, (size_t)size, &buf)) {
|
||||
blob = buf.buf;
|
||||
size = buf.len;
|
||||
}
|
||||
if (write_in_full(fd, blob, size) != size)
|
||||
die("unable to write temp-file");
|
||||
die_errno("unable to write temp-file");
|
||||
close(fd);
|
||||
temp->name = temp->tmp_path;
|
||||
strcpy(temp->hex, sha1_to_hex(sha1));
|
||||
@@ -2021,12 +2022,12 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
|
||||
if (lstat(name, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
goto not_a_valid_file;
|
||||
die("stat(%s): %s", name, strerror(errno));
|
||||
die_errno("stat(%s)", name);
|
||||
}
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
if (strbuf_readlink(&sb, name, st.st_size) < 0)
|
||||
die("readlink(%s)", name);
|
||||
die_errno("readlink(%s)", name);
|
||||
prep_temp_blob(name, temp, sb.buf, sb.len,
|
||||
(one->sha1_valid ?
|
||||
one->sha1 : null_sha1),
|
||||
@@ -2219,7 +2220,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
|
||||
return;
|
||||
}
|
||||
if (lstat(one->path, &st) < 0)
|
||||
die("stat %s", one->path);
|
||||
die_errno("stat '%s'", one->path);
|
||||
if (index_path(one->sha1, one->path, &st, 0))
|
||||
die("cannot hash %s", one->path);
|
||||
}
|
||||
|
||||
2
dir.c
2
dir.c
@@ -759,7 +759,7 @@ char *get_relative_cwd(char *buffer, int size, const char *dir)
|
||||
if (!dir)
|
||||
return NULL;
|
||||
if (!getcwd(buffer, size))
|
||||
die("can't find the current directory: %s", strerror(errno));
|
||||
die_errno("can't find the current directory");
|
||||
|
||||
if (!is_absolute_path(dir))
|
||||
dir = make_absolute_path(dir);
|
||||
|
||||
10
entry.c
10
entry.c
@@ -37,7 +37,7 @@ static void create_directories(const char *path, int path_len,
|
||||
if (errno == EEXIST && state->force &&
|
||||
!unlink_or_warn(buf) && !mkdir(buf, 0777))
|
||||
continue;
|
||||
die("cannot create directory at %s", buf);
|
||||
die_errno("cannot create directory at '%s'", buf);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
@@ -51,7 +51,7 @@ static void remove_subtree(const char *path)
|
||||
char *name;
|
||||
|
||||
if (!dir)
|
||||
die("cannot opendir %s (%s)", path, strerror(errno));
|
||||
die_errno("cannot opendir '%s'", path);
|
||||
strcpy(pathbuf, path);
|
||||
name = pathbuf + strlen(path);
|
||||
*name++ = '/';
|
||||
@@ -61,15 +61,15 @@ static void remove_subtree(const char *path)
|
||||
continue;
|
||||
strcpy(name, de->d_name);
|
||||
if (lstat(pathbuf, &st))
|
||||
die("cannot lstat %s (%s)", pathbuf, strerror(errno));
|
||||
die_errno("cannot lstat '%s'", pathbuf);
|
||||
if (S_ISDIR(st.st_mode))
|
||||
remove_subtree(pathbuf);
|
||||
else if (unlink(pathbuf))
|
||||
die("cannot unlink %s (%s)", pathbuf, strerror(errno));
|
||||
die_errno("cannot unlink '%s'", pathbuf);
|
||||
}
|
||||
closedir(dir);
|
||||
if (rmdir(path))
|
||||
die("cannot rmdir %s (%s)", path, strerror(errno));
|
||||
die_errno("cannot rmdir '%s'", path);
|
||||
}
|
||||
|
||||
static int create_file(const char *path, unsigned int mode)
|
||||
|
||||
@@ -905,10 +905,10 @@ static char *keep_pack(char *curr_index_name)
|
||||
|
||||
keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
|
||||
if (keep_fd < 0)
|
||||
die("cannot create keep file");
|
||||
die_errno("cannot create keep file");
|
||||
write_or_die(keep_fd, keep_msg, strlen(keep_msg));
|
||||
if (close(keep_fd))
|
||||
die("failed to write keep file");
|
||||
die_errno("failed to write keep file");
|
||||
|
||||
snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
|
||||
get_object_directory(), sha1_to_hex(pack_data->sha1));
|
||||
@@ -2342,7 +2342,7 @@ static void import_marks(const char *input_file)
|
||||
char line[512];
|
||||
FILE *f = fopen(input_file, "r");
|
||||
if (!f)
|
||||
die("cannot read %s: %s", input_file, strerror(errno));
|
||||
die_errno("cannot read '%s'", input_file);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
uintmax_t mark;
|
||||
char *end;
|
||||
@@ -2448,7 +2448,7 @@ int main(int argc, const char **argv)
|
||||
fclose(pack_edges);
|
||||
pack_edges = fopen(a + 20, "a");
|
||||
if (!pack_edges)
|
||||
die("Cannot open %s: %s", a + 20, strerror(errno));
|
||||
die_errno("Cannot open '%s'", a + 20);
|
||||
} else if (!strcmp(a, "--force"))
|
||||
force_update = 1;
|
||||
else if (!strcmp(a, "--quiet"))
|
||||
|
||||
2
fsck.c
2
fsck.c
@@ -229,7 +229,7 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
|
||||
struct commit_graft *graft;
|
||||
int parents = 0;
|
||||
|
||||
if (!commit->date)
|
||||
if (commit->date == ULONG_MAX)
|
||||
return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line");
|
||||
|
||||
if (memcmp(buffer, "tree ", 5))
|
||||
|
||||
166
git-am.sh
166
git-am.sh
@@ -11,6 +11,7 @@ git am [options] (--resolved | --skip | --abort)
|
||||
i,interactive run interactively
|
||||
b,binary* (historical option -- no-op)
|
||||
3,3way allow fall back on 3way merging if needed
|
||||
q,quiet be quiet
|
||||
s,signoff add a Signed-off-by line to the commit message
|
||||
u,utf8 recode into utf8 (default)
|
||||
k,keep pass -k flag to git-mailinfo
|
||||
@@ -18,6 +19,7 @@ whitespace= pass it through git-apply
|
||||
directory= pass it through git-apply
|
||||
C= pass it through git-apply
|
||||
p= pass it through git-apply
|
||||
patch-format= format the patch(es) are in
|
||||
reject pass it through git-apply
|
||||
resolvemsg= override error message when patch failure occurs
|
||||
r,resolved to be used after a patch failure
|
||||
@@ -99,7 +101,7 @@ fall_back_3way () {
|
||||
git write-tree >"$dotest/patch-merge-base+" ||
|
||||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
|
||||
|
||||
echo Using index info to reconstruct a base tree...
|
||||
say Using index info to reconstruct a base tree...
|
||||
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
git apply --cached <"$dotest/patch"
|
||||
then
|
||||
@@ -115,7 +117,7 @@ It does not apply to blobs recorded in its index."
|
||||
orig_tree=$(cat "$dotest/patch-merge-base") &&
|
||||
rm -fr "$dotest"/patch-merge-* || exit 1
|
||||
|
||||
echo Falling back to patching base and 3-way merge...
|
||||
say Falling back to patching base and 3-way merge...
|
||||
|
||||
# This is not so wrong. Depending on which base we picked,
|
||||
# orig_tree may be wildly different from ours, but his_tree
|
||||
@@ -125,6 +127,10 @@ It does not apply to blobs recorded in its index."
|
||||
|
||||
eval GITHEAD_$his_tree='"$FIRSTLINE"'
|
||||
export GITHEAD_$his_tree
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
export GIT_MERGE_VERBOSITY=0
|
||||
fi
|
||||
git-merge-recursive $orig_tree -- HEAD $his_tree || {
|
||||
git rerere
|
||||
echo Failed to merge in the changes.
|
||||
@@ -133,6 +139,126 @@ It does not apply to blobs recorded in its index."
|
||||
unset GITHEAD_$his_tree
|
||||
}
|
||||
|
||||
clean_abort () {
|
||||
test $# = 0 || echo >&2 "$@"
|
||||
rm -fr "$dotest"
|
||||
exit 1
|
||||
}
|
||||
|
||||
patch_format=
|
||||
|
||||
check_patch_format () {
|
||||
# early return if patch_format was set from the command line
|
||||
if test -n "$patch_format"
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# we default to mbox format if input is from stdin and for
|
||||
# directories
|
||||
if test $# = 0 || test "x$1" = "x-" || test -d "$1"
|
||||
then
|
||||
patch_format=mbox
|
||||
return 0
|
||||
fi
|
||||
|
||||
# otherwise, check the first few lines of the first patch to try
|
||||
# to detect its format
|
||||
{
|
||||
read l1
|
||||
read l2
|
||||
read l3
|
||||
case "$l1" in
|
||||
"From "* | "From: "*)
|
||||
patch_format=mbox
|
||||
;;
|
||||
'# This series applies on GIT commit'*)
|
||||
patch_format=stgit-series
|
||||
;;
|
||||
"# HG changeset patch")
|
||||
patch_format=hg
|
||||
;;
|
||||
*)
|
||||
# if the second line is empty and the third is
|
||||
# a From, Author or Date entry, this is very
|
||||
# likely an StGIT patch
|
||||
case "$l2,$l3" in
|
||||
,"From: "* | ,"Author: "* | ,"Date: "*)
|
||||
patch_format=stgit
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
} < "$1" || clean_abort
|
||||
}
|
||||
|
||||
split_patches () {
|
||||
case "$patch_format" in
|
||||
mbox)
|
||||
git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||
|
||||
clean_abort
|
||||
;;
|
||||
stgit-series)
|
||||
if test $# -ne 1
|
||||
then
|
||||
clean_abort "Only one StGIT patch series can be applied at once"
|
||||
fi
|
||||
series_dir=`dirname "$1"`
|
||||
series_file="$1"
|
||||
shift
|
||||
{
|
||||
set x
|
||||
while read filename
|
||||
do
|
||||
set "$@" "$series_dir/$filename"
|
||||
done
|
||||
# remove the safety x
|
||||
shift
|
||||
# remove the arg coming from the first-line comment
|
||||
shift
|
||||
} < "$series_file" || clean_abort
|
||||
# set the patch format appropriately
|
||||
patch_format=stgit
|
||||
# now handle the actual StGIT patches
|
||||
split_patches "$@"
|
||||
;;
|
||||
stgit)
|
||||
this=0
|
||||
for stgit in "$@"
|
||||
do
|
||||
this=`expr "$this" + 1`
|
||||
msgnum=`printf "%0${prec}d" $this`
|
||||
# Perl version of StGIT parse_patch. The first nonemptyline
|
||||
# not starting with Author, From or Date is the
|
||||
# subject, and the body starts with the next nonempty
|
||||
# line not starting with Author, From or Date
|
||||
perl -ne 'BEGIN { $subject = 0 }
|
||||
if ($subject > 1) { print ; }
|
||||
elsif (/^\s+$/) { next ; }
|
||||
elsif (/^Author:/) { print s/Author/From/ ; }
|
||||
elsif (/^(From|Date)/) { print ; }
|
||||
elsif ($subject) {
|
||||
$subject = 2 ;
|
||||
print "\n" ;
|
||||
print ;
|
||||
} else {
|
||||
print "Subject: ", $_ ;
|
||||
$subject = 1;
|
||||
}
|
||||
' < "$stgit" > "$dotest/$msgnum" || clean_abort
|
||||
done
|
||||
echo "$this" > "$dotest/last"
|
||||
this=
|
||||
msgnum=
|
||||
;;
|
||||
*)
|
||||
clean_abort "Patch format $patch_format is not supported."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
prec=4
|
||||
dotest="$GIT_DIR/rebase-apply"
|
||||
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
|
||||
@@ -175,12 +301,16 @@ do
|
||||
git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
|
||||
-C|-p)
|
||||
git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
|
||||
--patch-format)
|
||||
shift ; patch_format="$1" ;;
|
||||
--reject)
|
||||
git_apply_opt="$git_apply_opt $1" ;;
|
||||
--committer-date-is-author-date)
|
||||
committer_date_is_author_date=t ;;
|
||||
--ignore-date)
|
||||
ignore_date=t ;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t ;;
|
||||
--)
|
||||
shift; break ;;
|
||||
*)
|
||||
@@ -274,12 +404,12 @@ else
|
||||
done
|
||||
shift
|
||||
fi
|
||||
git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || {
|
||||
rm -fr "$dotest"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# -s, -u, -k, --whitespace, -3, -C and -p flags are kept
|
||||
check_patch_format "$@"
|
||||
|
||||
split_patches "$@"
|
||||
|
||||
# -s, -u, -k, --whitespace, -3, -C, -q and -p flags are kept
|
||||
# for the resuming session after a patch failure.
|
||||
# -i can and must be given when resuming.
|
||||
echo " $git_apply_opt" >"$dotest/apply-opt"
|
||||
@@ -287,6 +417,7 @@ else
|
||||
echo "$sign" >"$dotest/sign"
|
||||
echo "$utf8" >"$dotest/utf8"
|
||||
echo "$keep" >"$dotest/keep"
|
||||
echo "$GIT_QUIET" >"$dotest/quiet"
|
||||
echo 1 >"$dotest/next"
|
||||
if test -n "$rebasing"
|
||||
then
|
||||
@@ -327,6 +458,10 @@ if test "$(cat "$dotest/keep")" = t
|
||||
then
|
||||
keep=-k
|
||||
fi
|
||||
if test "$(cat "$dotest/quiet")" = t
|
||||
then
|
||||
GIT_QUIET=t
|
||||
fi
|
||||
if test "$(cat "$dotest/threeway")" = t
|
||||
then
|
||||
threeway=t
|
||||
@@ -352,7 +487,7 @@ fi
|
||||
|
||||
if test "$this" -gt "$last"
|
||||
then
|
||||
echo Nothing to do.
|
||||
say Nothing to do.
|
||||
rm -fr "$dotest"
|
||||
exit
|
||||
fi
|
||||
@@ -498,11 +633,18 @@ do
|
||||
stop_here $this
|
||||
fi
|
||||
|
||||
printf 'Applying: %s\n' "$FIRSTLINE"
|
||||
say "Applying: $FIRSTLINE"
|
||||
|
||||
case "$resolved" in
|
||||
'')
|
||||
eval 'git apply '"$git_apply_opt"' --index "$dotest/patch"'
|
||||
# When we are allowed to fall back to 3-way later, don't give
|
||||
# false errors during the initial attempt.
|
||||
squelch=
|
||||
if test "$threeway" = t
|
||||
then
|
||||
squelch='>/dev/null 2>&1 '
|
||||
fi
|
||||
eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"'
|
||||
apply_status=$?
|
||||
;;
|
||||
t)
|
||||
@@ -534,7 +676,7 @@ do
|
||||
# Applying the patch to an earlier tree and merging the
|
||||
# result may have produced the same tree as ours.
|
||||
git diff-index --quiet --cached HEAD -- && {
|
||||
echo No changes -- Patch already applied.
|
||||
say No changes -- Patch already applied.
|
||||
go_next
|
||||
continue
|
||||
}
|
||||
@@ -560,7 +702,7 @@ do
|
||||
GIT_AUTHOR_DATE=
|
||||
fi
|
||||
parent=$(git rev-parse --verify -q HEAD) ||
|
||||
echo >&2 "applying to an empty history"
|
||||
say >&2 "applying to an empty history"
|
||||
|
||||
if test -n "$committer_date_is_author_date"
|
||||
then
|
||||
|
||||
@@ -175,6 +175,7 @@ extern char *gitbasename(char *);
|
||||
/* General helper functions */
|
||||
extern void usage(const char *err) NORETURN;
|
||||
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
||||
extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
||||
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||
extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
|
||||
@@ -259,7 +259,8 @@ if (@canstatusfiles) {
|
||||
if $file =~ /^no file /
|
||||
&& $status eq 'Up-to-date';
|
||||
|
||||
$cvsstat{$fullname{$file}} = $status;
|
||||
$cvsstat{$fullname{$file}} = $status
|
||||
if defined $fullname{$file};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +300,7 @@ foreach my $f (@files) {
|
||||
while (<FILTER_IN>)
|
||||
{
|
||||
my $line = $_;
|
||||
$line =~ s/\$([A-Z][a-z]+):[^\$]+\$/\$\1\$/g;
|
||||
$line =~ s/\$([A-Z][a-z]+):[^\$]+\$/\$$1\$/g;
|
||||
print FILTER_OUT $line;
|
||||
}
|
||||
close FILTER_IN;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Copyright (c) 2005 Junio C Hamano.
|
||||
#
|
||||
|
||||
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>]'
|
||||
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
|
||||
LONG_USAGE='git-rebase replaces <branch> with a new branch of the
|
||||
same name. When the --onto option is provided the new branch starts
|
||||
out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
|
||||
@@ -72,11 +72,20 @@ continue_merge () {
|
||||
echo "directly, but instead do one of the following: "
|
||||
die "$RESOLVEMSG"
|
||||
fi
|
||||
printf "Committed: %0${prec}d " $msgnum
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Committed: %0${prec}d " $msgnum
|
||||
fi
|
||||
else
|
||||
printf "Already applied: %0${prec}d " $msgnum
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Already applied: %0${prec}d " $msgnum
|
||||
fi
|
||||
fi
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //'
|
||||
fi
|
||||
git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //'
|
||||
|
||||
prev_head=`git rev-parse HEAD^0`
|
||||
# save the resulting commit so we can read-tree on it later
|
||||
@@ -97,6 +106,10 @@ call_merge () {
|
||||
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
|
||||
eval GITHEAD_$hd='$(cat "$dotest/onto_name")'
|
||||
export GITHEAD_$cmt GITHEAD_$hd
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
export GIT_MERGE_VERBOSITY=1
|
||||
fi
|
||||
git-merge-$strategy "$cmt^" -- "$hd" "$cmt"
|
||||
rv=$?
|
||||
case "$rv" in
|
||||
@@ -138,7 +151,7 @@ move_to_original_branch () {
|
||||
finish_rb_merge () {
|
||||
move_to_original_branch
|
||||
rm -r "$dotest"
|
||||
echo "All done."
|
||||
say All done.
|
||||
}
|
||||
|
||||
is_interactive () {
|
||||
@@ -207,6 +220,7 @@ do
|
||||
end=$(cat "$dotest/end")
|
||||
msgnum=$(cat "$dotest/msgnum")
|
||||
onto=$(cat "$dotest/onto")
|
||||
GIT_QUIET=$(cat "$dotest/quiet")
|
||||
continue_merge
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
@@ -219,6 +233,7 @@ do
|
||||
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
|
||||
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
|
||||
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
|
||||
GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
|
||||
git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
|
||||
move_to_original_branch
|
||||
exit
|
||||
@@ -236,6 +251,7 @@ do
|
||||
msgnum=$(cat "$dotest/msgnum")
|
||||
msgnum=$(($msgnum + 1))
|
||||
onto=$(cat "$dotest/onto")
|
||||
GIT_QUIET=$(cat "$dotest/quiet")
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
call_merge "$msgnum"
|
||||
@@ -247,6 +263,7 @@ do
|
||||
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
|
||||
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
|
||||
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
|
||||
GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
|
||||
git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
|
||||
move_to_original_branch
|
||||
exit
|
||||
@@ -258,9 +275,11 @@ do
|
||||
git rerere clear
|
||||
if test -d "$dotest"
|
||||
then
|
||||
GIT_QUIET=$(cat "$dotest/quiet")
|
||||
move_to_original_branch
|
||||
else
|
||||
dotest="$GIT_DIR"/rebase-apply
|
||||
GIT_QUIET=$(cat "$dotest/quiet")
|
||||
move_to_original_branch
|
||||
fi
|
||||
git reset --hard $(cat "$dotest/orig-head")
|
||||
@@ -298,6 +317,13 @@ do
|
||||
-v|--verbose)
|
||||
verbose=t
|
||||
diffstat=t
|
||||
GIT_QUIET=
|
||||
;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
git_am_opt="$git_am_opt -q"
|
||||
verbose=
|
||||
diffstat=
|
||||
;;
|
||||
--whitespace=*)
|
||||
git_am_opt="$git_am_opt $1"
|
||||
@@ -442,15 +468,15 @@ then
|
||||
then
|
||||
# Lazily switch to the target branch if needed...
|
||||
test -z "$switch_to" || git checkout "$switch_to"
|
||||
echo >&2 "Current branch $branch_name is up to date."
|
||||
say "Current branch $branch_name is up to date."
|
||||
exit 0
|
||||
else
|
||||
echo "Current branch $branch_name is up to date, rebase forced."
|
||||
say "Current branch $branch_name is up to date, rebase forced."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detach HEAD and reset the tree
|
||||
echo "First, rewinding head to replay your work on top of it..."
|
||||
say "First, rewinding head to replay your work on top of it..."
|
||||
git checkout -q "$onto^0" || die "could not detach HEAD"
|
||||
git update-ref ORIG_HEAD $branch
|
||||
|
||||
@@ -468,7 +494,7 @@ fi
|
||||
# we just fast forwarded.
|
||||
if test "$mb" = "$branch"
|
||||
then
|
||||
echo >&2 "Fast-forwarded $branch_name to $onto_name."
|
||||
say "Fast-forwarded $branch_name to $onto_name."
|
||||
move_to_original_branch
|
||||
exit 0
|
||||
fi
|
||||
@@ -490,7 +516,8 @@ then
|
||||
test 0 != $ret -a -d "$GIT_DIR"/rebase-apply &&
|
||||
echo $head_name > "$GIT_DIR"/rebase-apply/head-name &&
|
||||
echo $onto > "$GIT_DIR"/rebase-apply/onto &&
|
||||
echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head
|
||||
echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head &&
|
||||
echo "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
@@ -504,6 +531,7 @@ prev_head=$orig_head
|
||||
echo "$prev_head" > "$dotest/prev_head"
|
||||
echo "$orig_head" > "$dotest/orig-head"
|
||||
echo "$head_name" > "$dotest/head-name"
|
||||
echo "$GIT_QUIET" > "$dotest/quiet"
|
||||
|
||||
msgnum=0
|
||||
for cmt in `git rev-list --reverse --no-merges "$revisions"`
|
||||
|
||||
@@ -24,7 +24,7 @@ SUBDIRECTORY_OK='Yes'
|
||||
. git-sh-setup
|
||||
|
||||
no_update_info= all_into_one= remove_redundant= unpack_unreachable=
|
||||
local= quiet= no_reuse= extra=
|
||||
local= no_reuse= extra=
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
@@ -33,7 +33,7 @@ do
|
||||
-A) all_into_one=t
|
||||
unpack_unreachable=--unpack-unreachable ;;
|
||||
-d) remove_redundant=t ;;
|
||||
-q) quiet=-q ;;
|
||||
-q) GIT_QUIET=t ;;
|
||||
-f) no_reuse=--no-reuse-object ;;
|
||||
-l) local=--local ;;
|
||||
--max-pack-size|--window|--window-memory|--depth)
|
||||
@@ -80,13 +80,11 @@ case ",$all_into_one," in
|
||||
;;
|
||||
esac
|
||||
|
||||
args="$args $local $quiet $no_reuse$extra"
|
||||
args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra"
|
||||
names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
|
||||
exit 1
|
||||
if [ -z "$names" ]; then
|
||||
if test -z "$quiet"; then
|
||||
echo Nothing new to pack.
|
||||
fi
|
||||
say Nothing new to pack.
|
||||
fi
|
||||
|
||||
# Ok we have prepared all new packfiles.
|
||||
@@ -176,7 +174,7 @@ then
|
||||
done
|
||||
)
|
||||
fi
|
||||
git prune-packed $quiet
|
||||
git prune-packed ${GIT_QUIET:+-q}
|
||||
fi
|
||||
|
||||
case "$no_update_info" in
|
||||
|
||||
@@ -12,6 +12,9 @@ OPTIONS_SPEC=
|
||||
. git-sh-setup
|
||||
. git-parse-remote
|
||||
|
||||
GIT_PAGER=
|
||||
export GIT_PAGER
|
||||
|
||||
base=$1
|
||||
url=$2
|
||||
head=${3-HEAD}
|
||||
@@ -34,7 +37,7 @@ branch=$(git ls-remote "$url" \
|
||||
}")
|
||||
if [ -z "$branch" ]; then
|
||||
echo "warn: No branch of $url is at:" >&2
|
||||
git log --max-count=1 --pretty='format:warn: %h: %s' $headrev >&2
|
||||
git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2
|
||||
echo "warn: Are you sure you pushed $head there?" >&2
|
||||
echo >&2
|
||||
echo >&2
|
||||
@@ -42,8 +45,6 @@ if [ -z "$branch" ]; then
|
||||
status=1
|
||||
fi
|
||||
|
||||
PAGER=
|
||||
export PAGER
|
||||
echo "The following changes since commit $baserev:"
|
||||
git shortlog --max-count=1 $baserev | sed -e 's/^\(.\)/ \1/'
|
||||
|
||||
|
||||
@@ -44,6 +44,15 @@ die() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
GIT_QUIET=
|
||||
|
||||
say () {
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf '%s\n' "$*"
|
||||
fi
|
||||
}
|
||||
|
||||
if test -n "$OPTIONS_SPEC"; then
|
||||
usage() {
|
||||
"$0" -h
|
||||
|
||||
78
git-stash.sh
78
git-stash.sh
@@ -3,10 +3,11 @@
|
||||
|
||||
dashless=$(basename "$0" | sed -e 's/-/ /')
|
||||
USAGE="list [<options>]
|
||||
or: $dashless ( show | drop ) [<stash>]
|
||||
or: $dashless ( pop | apply ) [--index] [<stash>]
|
||||
or: $dashless show [<stash>]
|
||||
or: $dashless drop [-q|--quiet] [<stash>]
|
||||
or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
|
||||
or: $dashless branch <branchname> [<stash>]
|
||||
or: $dashless [save [--keep-index] [<message>]]
|
||||
or: $dashless [save [--keep-index] [-q|--quiet] [<message>]]
|
||||
or: $dashless clear"
|
||||
|
||||
SUBDIRECTORY_OK=Yes
|
||||
@@ -94,18 +95,28 @@ create_stash () {
|
||||
|
||||
save_stash () {
|
||||
keep_index=
|
||||
case "$1" in
|
||||
--keep-index)
|
||||
keep_index=t
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
--keep-index)
|
||||
keep_index=t
|
||||
;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
esac
|
||||
done
|
||||
|
||||
stash_msg="$*"
|
||||
|
||||
git update-index -q --refresh
|
||||
if no_changes
|
||||
then
|
||||
echo 'No local changes to save'
|
||||
say 'No local changes to save'
|
||||
exit 0
|
||||
fi
|
||||
test -f "$GIT_DIR/logs/$ref_stash" ||
|
||||
@@ -118,9 +129,9 @@ save_stash () {
|
||||
|
||||
git update-ref -m "$stash_msg" $ref_stash $w_commit ||
|
||||
die "Cannot save the current status"
|
||||
printf 'Saved working directory and index state "%s"\n' "$stash_msg"
|
||||
say Saved working directory and index state "$stash_msg"
|
||||
|
||||
git reset --hard
|
||||
git reset --hard ${GIT_QUIET:+-q}
|
||||
|
||||
if test -n "$keep_index" && test -n $i_tree
|
||||
then
|
||||
@@ -156,11 +167,22 @@ apply_stash () {
|
||||
die 'Cannot apply to a dirty working tree, please stage your changes'
|
||||
|
||||
unstash_index=
|
||||
case "$1" in
|
||||
--index)
|
||||
unstash_index=t
|
||||
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
--index)
|
||||
unstash_index=t
|
||||
;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
esac
|
||||
done
|
||||
|
||||
# current index state
|
||||
c_tree=$(git write-tree) ||
|
||||
@@ -193,6 +215,10 @@ apply_stash () {
|
||||
export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree
|
||||
"
|
||||
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
export GIT_MERGE_VERBOSITY=0
|
||||
fi
|
||||
if git-merge-recursive $b_tree -- $c_tree $w_tree
|
||||
then
|
||||
# No conflict
|
||||
@@ -207,7 +233,12 @@ apply_stash () {
|
||||
die "Cannot unstage modified files"
|
||||
rm -f "$a"
|
||||
fi
|
||||
git status || :
|
||||
squelch=
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
squelch='>/dev/null 2>&1'
|
||||
fi
|
||||
eval "git status $squelch" || :
|
||||
else
|
||||
# Merge conflict; keep the exit status from merge-recursive
|
||||
status=$?
|
||||
@@ -222,6 +253,19 @@ apply_stash () {
|
||||
drop_stash () {
|
||||
have_stash || die 'No stash entries to drop'
|
||||
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# = 0
|
||||
then
|
||||
set x "$ref_stash@{0}"
|
||||
@@ -235,7 +279,7 @@ drop_stash () {
|
||||
die "$*: not a valid stashed state"
|
||||
|
||||
git reflog delete --updateref --rewrite "$@" &&
|
||||
echo "Dropped $* ($s)" || die "$*: Could not drop stash entry"
|
||||
say "Dropped $* ($s)" || die "$*: Could not drop stash entry"
|
||||
|
||||
# clear_stash if we just dropped the last stash entry
|
||||
git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash
|
||||
@@ -312,7 +356,7 @@ branch)
|
||||
if test $# -eq 0
|
||||
then
|
||||
save_stash &&
|
||||
echo '(To restore them type "git stash apply")'
|
||||
say '(To restore them type "git stash apply")'
|
||||
else
|
||||
usage
|
||||
fi
|
||||
|
||||
@@ -14,23 +14,11 @@ require_work_tree
|
||||
|
||||
command=
|
||||
branch=
|
||||
quiet=
|
||||
reference=
|
||||
cached=
|
||||
nofetch=
|
||||
update=
|
||||
|
||||
#
|
||||
# print stuff on stdout unless -q was specified
|
||||
#
|
||||
say()
|
||||
{
|
||||
if test -z "$quiet"
|
||||
then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Resolve relative url by appending to parent's url
|
||||
resolve_relative_url ()
|
||||
{
|
||||
@@ -137,7 +125,7 @@ cmd_add()
|
||||
shift
|
||||
;;
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
--reference)
|
||||
case "$2" in '') usage ;; esac
|
||||
@@ -273,7 +261,7 @@ cmd_init()
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
@@ -333,7 +321,7 @@ cmd_update()
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
shift
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
-i|--init)
|
||||
init=1
|
||||
@@ -659,7 +647,7 @@ cmd_status()
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
--cached)
|
||||
cached=1
|
||||
@@ -713,7 +701,7 @@ cmd_sync()
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
@@ -768,7 +756,7 @@ do
|
||||
command=$1
|
||||
;;
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
-b|--branch)
|
||||
case "$2" in
|
||||
|
||||
173
git-svn.perl
173
git-svn.perl
@@ -63,7 +63,7 @@ my ($SVN);
|
||||
$sha1 = qr/[a-f\d]{40}/;
|
||||
$sha1_short = qr/[a-f\d]{4,40}/;
|
||||
my ($_stdin, $_help, $_edit,
|
||||
$_message, $_file,
|
||||
$_message, $_file, $_branch_dest,
|
||||
$_template, $_shared,
|
||||
$_version, $_fetch_all, $_no_rebase, $_fetch_parent,
|
||||
$_merge, $_strategy, $_dry_run, $_local,
|
||||
@@ -92,11 +92,11 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
|
||||
'localtime' => \$Git::SVN::_localtime,
|
||||
%remote_opts );
|
||||
|
||||
my ($_trunk, $_tags, $_branches, $_stdlayout);
|
||||
my ($_trunk, @_tags, @_branches, $_stdlayout);
|
||||
my %icv;
|
||||
my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
|
||||
'trunk|T=s' => \$_trunk, 'tags|t=s' => \$_tags,
|
||||
'branches|b=s' => \$_branches, 'prefix=s' => \$_prefix,
|
||||
'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
|
||||
'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
|
||||
'stdlayout|s' => \$_stdlayout,
|
||||
'minimize-url|m' => \$Git::SVN::_minimize_url,
|
||||
'no-metadata' => sub { $icv{noMetadata} = 1 },
|
||||
@@ -141,11 +141,13 @@ my %cmd = (
|
||||
branch => [ \&cmd_branch,
|
||||
'Create a branch in the SVN repository',
|
||||
{ 'message|m=s' => \$_message,
|
||||
'destination|d=s' => \$_branch_dest,
|
||||
'dry-run|n' => \$_dry_run,
|
||||
'tag|t' => \$_tag } ],
|
||||
tag => [ sub { $_tag = 1; cmd_branch(@_) },
|
||||
'Create a tag in the SVN repository',
|
||||
{ 'message|m=s' => \$_message,
|
||||
'destination|d=s' => \$_branch_dest,
|
||||
'dry-run|n' => \$_dry_run } ],
|
||||
'set-tree' => [ \&cmd_set_tree,
|
||||
"Set an SVN repository to a git tree-ish",
|
||||
@@ -211,6 +213,10 @@ my %cmd = (
|
||||
'blame' => [ \&Git::SVN::Log::cmd_blame,
|
||||
"Show what revision and author last modified each line of a file",
|
||||
{ 'git-format' => \$_git_format } ],
|
||||
'reset' => [ \&cmd_reset,
|
||||
"Undo fetches back to the specified SVN revision",
|
||||
{ 'revision|r=s' => \$_revision,
|
||||
'parent|p' => \$_fetch_parent } ],
|
||||
);
|
||||
|
||||
my $cmd;
|
||||
@@ -219,6 +225,9 @@ for (my $i = 0; $i < @ARGV; $i++) {
|
||||
$cmd = $ARGV[$i];
|
||||
splice @ARGV, $i, 1;
|
||||
last;
|
||||
} elsif ($ARGV[$i] eq 'help') {
|
||||
$cmd = $ARGV[$i+1];
|
||||
usage(0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -358,7 +367,7 @@ sub init_subdir {
|
||||
sub cmd_clone {
|
||||
my ($url, $path) = @_;
|
||||
if (!defined $path &&
|
||||
(defined $_trunk || defined $_branches || defined $_tags ||
|
||||
(defined $_trunk || @_branches || @_tags ||
|
||||
defined $_stdlayout) &&
|
||||
$url !~ m#^[a-z\+]+://#) {
|
||||
$path = $url;
|
||||
@@ -372,14 +381,15 @@ sub cmd_clone {
|
||||
sub cmd_init {
|
||||
if (defined $_stdlayout) {
|
||||
$_trunk = 'trunk' if (!defined $_trunk);
|
||||
$_tags = 'tags' if (!defined $_tags);
|
||||
$_branches = 'branches' if (!defined $_branches);
|
||||
@_tags = 'tags' if (! @_tags);
|
||||
@_branches = 'branches' if (! @_branches);
|
||||
}
|
||||
if (defined $_trunk || defined $_branches || defined $_tags) {
|
||||
if (defined $_trunk || @_branches || @_tags) {
|
||||
return cmd_multi_init(@_);
|
||||
}
|
||||
my $url = shift or die "SVN repository location required ",
|
||||
"as a command-line argument\n";
|
||||
$url = canonicalize_url($url);
|
||||
init_subdir(@_);
|
||||
do_git_init_db();
|
||||
|
||||
@@ -454,8 +464,22 @@ sub cmd_dcommit {
|
||||
'Cannot dcommit with a dirty index. Commit your changes first, '
|
||||
. "or stash them with `git stash'.\n";
|
||||
$head ||= 'HEAD';
|
||||
|
||||
my $old_head;
|
||||
if ($head ne 'HEAD') {
|
||||
$old_head = eval {
|
||||
command_oneline([qw/symbolic-ref -q HEAD/])
|
||||
};
|
||||
if ($old_head) {
|
||||
$old_head =~ s{^refs/heads/}{};
|
||||
} else {
|
||||
$old_head = eval { command_oneline(qw/rev-parse HEAD/) };
|
||||
}
|
||||
command(['checkout', $head], STDERR => 0);
|
||||
}
|
||||
|
||||
my @refs;
|
||||
my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
|
||||
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD', \@refs);
|
||||
unless ($gs) {
|
||||
die "Unable to determine upstream SVN information from ",
|
||||
"$head history.\nPerhaps the repository is empty.";
|
||||
@@ -541,7 +565,7 @@ sub cmd_dcommit {
|
||||
if (@diff) {
|
||||
@refs = ();
|
||||
my ($url_, $rev_, $uuid_, $gs_) =
|
||||
working_head_info($head, \@refs);
|
||||
working_head_info('HEAD', \@refs);
|
||||
my ($linear_refs_, $parents_) =
|
||||
linearize_history($gs_, \@refs);
|
||||
if (scalar(@$linear_refs) !=
|
||||
@@ -579,6 +603,22 @@ sub cmd_dcommit {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($old_head) {
|
||||
my $new_head = command_oneline(qw/rev-parse HEAD/);
|
||||
my $new_is_symbolic = eval {
|
||||
command_oneline(qw/symbolic-ref -q HEAD/);
|
||||
};
|
||||
if ($new_is_symbolic) {
|
||||
print "dcommitted the branch ", $head, "\n";
|
||||
} else {
|
||||
print "dcommitted on a detached HEAD because you gave ",
|
||||
"a revision argument.\n",
|
||||
"The rewritten commit is: ", $new_head, "\n";
|
||||
}
|
||||
command(['checkout', $old_head], STDERR => 0);
|
||||
}
|
||||
|
||||
unlink $gs->{index};
|
||||
}
|
||||
|
||||
@@ -593,7 +633,33 @@ sub cmd_branch {
|
||||
my ($src, $rev, undef, $gs) = working_head_info($head);
|
||||
|
||||
my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}};
|
||||
my $glob = $remote->{ $_tag ? 'tags' : 'branches' };
|
||||
my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' };
|
||||
my $glob;
|
||||
if ($#{$allglobs} == 0) {
|
||||
$glob = $allglobs->[0];
|
||||
} else {
|
||||
unless(defined $_branch_dest) {
|
||||
die "Multiple ",
|
||||
$_tag ? "tag" : "branch",
|
||||
" paths defined for Subversion repository.\n",
|
||||
"You must specify where you want to create the ",
|
||||
$_tag ? "tag" : "branch",
|
||||
" with the --destination argument.\n";
|
||||
}
|
||||
foreach my $g (@{$allglobs}) {
|
||||
# SVN::Git::Editor could probably be moved to Git.pm..
|
||||
my $re = SVN::Git::Editor::glob2pat($g->{path}->{left});
|
||||
if ($_branch_dest =~ /$re/) {
|
||||
$glob = $g;
|
||||
last;
|
||||
}
|
||||
}
|
||||
unless (defined $glob) {
|
||||
die "Unknown ",
|
||||
$_tag ? "tag" : "branch",
|
||||
" destination $_branch_dest\n";
|
||||
}
|
||||
}
|
||||
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
|
||||
my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
|
||||
|
||||
@@ -741,6 +807,12 @@ sub canonicalize_path {
|
||||
return $path;
|
||||
}
|
||||
|
||||
sub canonicalize_url {
|
||||
my ($url) = @_;
|
||||
$url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
|
||||
return $url;
|
||||
}
|
||||
|
||||
# get_svnprops(PATH)
|
||||
# ------------------
|
||||
# Helper for cmd_propget and cmd_proplist below.
|
||||
@@ -800,7 +872,7 @@ sub cmd_proplist {
|
||||
|
||||
sub cmd_multi_init {
|
||||
my $url = shift;
|
||||
unless (defined $_trunk || defined $_branches || defined $_tags) {
|
||||
unless (defined $_trunk || @_branches || @_tags) {
|
||||
usage(1);
|
||||
}
|
||||
|
||||
@@ -810,7 +882,7 @@ sub cmd_multi_init {
|
||||
|
||||
$_prefix = '' unless defined $_prefix;
|
||||
if (defined $url) {
|
||||
$url =~ s#/+$##;
|
||||
$url = canonicalize_url($url);
|
||||
init_subdir(@_);
|
||||
}
|
||||
do_git_init_db();
|
||||
@@ -825,10 +897,14 @@ sub cmd_multi_init {
|
||||
undef, $trunk_ref);
|
||||
}
|
||||
}
|
||||
return unless defined $_branches || defined $_tags;
|
||||
return unless @_branches || @_tags;
|
||||
my $ra = $url ? Git::SVN::Ra->new($url) : undef;
|
||||
complete_url_ls_init($ra, $_branches, '--branches/-b', $_prefix);
|
||||
complete_url_ls_init($ra, $_tags, '--tags/-t', $_prefix . 'tags/');
|
||||
foreach my $path (@_branches) {
|
||||
complete_url_ls_init($ra, $path, '--branches/-b', $_prefix);
|
||||
}
|
||||
foreach my $path (@_tags) {
|
||||
complete_url_ls_init($ra, $path, '--tags/-t', $_prefix.'tags/');
|
||||
}
|
||||
}
|
||||
|
||||
sub cmd_multi_fetch {
|
||||
@@ -1021,6 +1097,20 @@ sub cmd_info {
|
||||
print $result, "\n";
|
||||
}
|
||||
|
||||
sub cmd_reset {
|
||||
my $target = shift || $_revision or die "SVN revision required\n";
|
||||
$target = $1 if $target =~ /^r(\d+)$/;
|
||||
$target =~ /^\d+$/ or die "Numeric SVN revision expected\n";
|
||||
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
|
||||
unless ($gs) {
|
||||
die "Unable to determine upstream SVN information from ".
|
||||
"history\n";
|
||||
}
|
||||
my ($r, $c) = $gs->find_rev_before($target, not $_fetch_parent);
|
||||
$gs->rev_map_set($r, $c, 'reset', $uuid);
|
||||
print "r$r = $c ($gs->{ref_id})\n";
|
||||
}
|
||||
|
||||
########################### utility functions #########################
|
||||
|
||||
sub rebase_cmd {
|
||||
@@ -1099,6 +1189,7 @@ sub complete_url_ls_init {
|
||||
die "--prefix='$pfx' must have a trailing slash '/'\n";
|
||||
}
|
||||
command_noisy('config',
|
||||
'--add',
|
||||
"svn-remote.$gs->{repo_id}.$n",
|
||||
"$remote_path:refs/remotes/$pfx*" .
|
||||
('/*' x (($remote_path =~ tr/*/*/) - 1)) );
|
||||
@@ -1565,7 +1656,8 @@ sub fetch_all {
|
||||
# read the max revs for wildcard expansion (branches/*, tags/*)
|
||||
foreach my $t (qw/branches tags/) {
|
||||
defined $remote->{$t} or next;
|
||||
push @globs, $remote->{$t};
|
||||
push @globs, @{$remote->{$t}};
|
||||
|
||||
my $max_rev = eval { tmp_config(qw/--int --get/,
|
||||
"svn-remote.$repo_id.${t}-maxRev") };
|
||||
if (defined $max_rev && ($max_rev < $base)) {
|
||||
@@ -1612,15 +1704,16 @@ sub read_all_remotes {
|
||||
} elsif (m!^(.+)\.(branches|tags)=
|
||||
(.*):refs/remotes/(.+)\s*$/!x) {
|
||||
my ($p, $g) = ($3, $4);
|
||||
my $rs = $r->{$1}->{$2} = {
|
||||
t => $2,
|
||||
remote => $1,
|
||||
path => Git::SVN::GlobSpec->new($p),
|
||||
ref => Git::SVN::GlobSpec->new($g) };
|
||||
my $rs = {
|
||||
t => $2,
|
||||
remote => $1,
|
||||
path => Git::SVN::GlobSpec->new($p),
|
||||
ref => Git::SVN::GlobSpec->new($g) };
|
||||
if (length($rs->{ref}->{right}) != 0) {
|
||||
die "The '*' glob character must be the last ",
|
||||
"character of '$g'\n";
|
||||
}
|
||||
push @{ $r->{$1}->{$2} }, $rs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1760,9 +1853,10 @@ sub find_by_url { # repos_root and, path are optional
|
||||
next if defined $repos_root && $repos_root ne $u;
|
||||
|
||||
my $fetch = $remotes->{$repo_id}->{fetch} || {};
|
||||
foreach (qw/branches tags/) {
|
||||
resolve_local_globs($u, $fetch,
|
||||
$remotes->{$repo_id}->{$_});
|
||||
foreach my $t (qw/branches tags/) {
|
||||
foreach my $globspec (@{$remotes->{$repo_id}->{$t}}) {
|
||||
resolve_local_globs($u, $fetch, $globspec);
|
||||
}
|
||||
}
|
||||
my $p = $path;
|
||||
my $rwr = rewrite_root({repo_id => $repo_id});
|
||||
@@ -2990,6 +3084,14 @@ sub _rev_map_set {
|
||||
croak "write: $!";
|
||||
}
|
||||
|
||||
sub _rev_map_reset {
|
||||
my ($fh, $rev, $commit) = @_;
|
||||
my $c = _rev_map_get($fh, $rev);
|
||||
$c eq $commit or die "_rev_map_reset(@_) commit $c does not match!\n";
|
||||
my $offset = sysseek($fh, 0, SEEK_CUR) or croak "seek: $!";
|
||||
truncate $fh, $offset or croak "truncate: $!";
|
||||
}
|
||||
|
||||
sub mkfile {
|
||||
my ($path) = @_;
|
||||
unless (-e $path) {
|
||||
@@ -3006,6 +3108,7 @@ sub rev_map_set {
|
||||
my $db = $self->map_path($uuid);
|
||||
my $db_lock = "$db.lock";
|
||||
my $sig;
|
||||
$update_ref ||= 0;
|
||||
if ($update_ref) {
|
||||
$SIG{INT} = $SIG{HUP} = $SIG{TERM} = $SIG{ALRM} = $SIG{PIPE} =
|
||||
$SIG{USR1} = $SIG{USR2} = sub { $sig = $_[0] };
|
||||
@@ -3029,7 +3132,8 @@ sub rev_map_set {
|
||||
|
||||
sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
|
||||
or croak "Couldn't open $db_lock: $!\n";
|
||||
_rev_map_set($fh, $rev, $commit);
|
||||
$update_ref eq 'reset' ? _rev_map_reset($fh, $rev, $commit) :
|
||||
_rev_map_set($fh, $rev, $commit);
|
||||
if ($sync) {
|
||||
$fh->flush or die "Couldn't flush $db_lock: $!\n";
|
||||
$fh->sync or die "Couldn't sync $db_lock: $!\n";
|
||||
@@ -3037,7 +3141,9 @@ sub rev_map_set {
|
||||
close $fh or croak $!;
|
||||
if ($update_ref) {
|
||||
$_head = $self;
|
||||
command_noisy('update-ref', '-m', "r$rev",
|
||||
my $note = "";
|
||||
$note = " ($update_ref)" if ($update_ref !~ /^\d*$/);
|
||||
command_noisy('update-ref', '-m', "r$rev$note",
|
||||
$self->refname, $commit);
|
||||
}
|
||||
rename $db_lock, $db or die "rev_map_set(@_): ", "Failed to rename: ",
|
||||
@@ -3099,12 +3205,19 @@ sub rev_map_get {
|
||||
return undef unless -e $map_path;
|
||||
|
||||
sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
|
||||
my $c = _rev_map_get($fh, $rev);
|
||||
close($fh) or croak "close: $!";
|
||||
$c
|
||||
}
|
||||
|
||||
sub _rev_map_get {
|
||||
my ($fh, $rev) = @_;
|
||||
|
||||
binmode $fh or croak "binmode: $!";
|
||||
my $size = (stat($fh))[7];
|
||||
($size % 24) == 0 or croak "inconsistent size: $size";
|
||||
|
||||
if ($size == 0) {
|
||||
close $fh or croak "close: $fh";
|
||||
return undef;
|
||||
}
|
||||
|
||||
@@ -3122,11 +3235,9 @@ sub rev_map_get {
|
||||
} elsif ($r > $rev) {
|
||||
$u = $i - 24;
|
||||
} else { # $r == $rev
|
||||
close($fh) or croak "close: $!";
|
||||
return $c eq ('0' x 40) ? undef : $c;
|
||||
}
|
||||
}
|
||||
close($fh) or croak "close: $!";
|
||||
undef;
|
||||
}
|
||||
|
||||
@@ -3138,6 +3249,8 @@ sub find_rev_before {
|
||||
my ($self, $rev, $eq_ok, $min_rev) = @_;
|
||||
--$rev unless $eq_ok;
|
||||
$min_rev ||= 1;
|
||||
my $max_rev = $self->rev_map_max;
|
||||
$rev = $max_rev if ($rev > $max_rev);
|
||||
while ($rev >= $min_rev) {
|
||||
if (my $c = $self->rev_map_get($rev)) {
|
||||
return ($rev, $c);
|
||||
|
||||
11
git.c
11
git.c
@@ -188,10 +188,9 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
alias_command);
|
||||
|
||||
new_argv = xrealloc(new_argv, sizeof(char *) *
|
||||
(count + *argcp + 1));
|
||||
(count + *argcp));
|
||||
/* insert after command name */
|
||||
memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);
|
||||
new_argv[count+*argcp] = NULL;
|
||||
|
||||
*argv = new_argv;
|
||||
*argcp += count - 1;
|
||||
@@ -200,7 +199,7 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
}
|
||||
|
||||
if (subdir && chdir(subdir))
|
||||
die("Cannot change to %s: %s", subdir, strerror(errno));
|
||||
die_errno("Cannot change to '%s'", subdir);
|
||||
|
||||
errno = saved_errno;
|
||||
|
||||
@@ -246,7 +245,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
||||
|
||||
status = p->fn(argc, argv, prefix);
|
||||
if (status)
|
||||
return status & 0xff;
|
||||
return status;
|
||||
|
||||
/* Somebody closed stdout? */
|
||||
if (fstat(fileno(stdout), &st))
|
||||
@@ -257,11 +256,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
||||
|
||||
/* Check for ENOSPC and EIO errors.. */
|
||||
if (fflush(stdout))
|
||||
die("write failure on standard output: %s", strerror(errno));
|
||||
die_errno("write failure on standard output");
|
||||
if (ferror(stdout))
|
||||
die("unknown write failure on standard output");
|
||||
if (fclose(stdout))
|
||||
die("close failed on standard output: %s", strerror(errno));
|
||||
die_errno("close failed on standard output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@ named without a .git extension (e.g. /pub/git/project instead of
|
||||
|
||||
DocumentRoot /var/www/gitweb
|
||||
|
||||
AliasMatch ^(/.*?)(\.git)(/.*)? /pub/git$1$3
|
||||
AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
|
||||
<Directory /var/www/gitweb>
|
||||
Options ExecCGI
|
||||
AddHandler cgi-script cgi
|
||||
@@ -402,6 +402,14 @@ http://git.example.com/project
|
||||
|
||||
will provide human-friendly gitweb access.
|
||||
|
||||
This solution is not 100% bulletproof, in the sense that if some project
|
||||
has a named ref (branch, tag) starting with 'git/', then paths such as
|
||||
|
||||
http://git.example.com/project/command/abranch..git/abranch
|
||||
|
||||
will fail with a 404 error.
|
||||
|
||||
|
||||
|
||||
Originally written by:
|
||||
Kay Sievers <kay.sievers@vrfy.org>
|
||||
|
||||
@@ -28,6 +28,10 @@ img.logo {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
img.avatar {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.page_header {
|
||||
height: 25px;
|
||||
padding: 8px;
|
||||
@@ -132,11 +136,14 @@ div.list_head {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.author_date, .author {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.author_date {
|
||||
padding: 8px;
|
||||
border: solid #d9d8d1;
|
||||
border-width: 0px 0px 1px 0px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
a.list {
|
||||
|
||||
@@ -195,6 +195,14 @@ our %known_snapshot_format_aliases = (
|
||||
'x-zip' => undef, '' => undef,
|
||||
);
|
||||
|
||||
# Pixel sizes for icons and avatars. If the default font sizes or lineheights
|
||||
# are changed, it may be appropriate to change these values too via
|
||||
# $GITWEB_CONFIG.
|
||||
our %avatar_size = (
|
||||
'default' => 16,
|
||||
'double' => 32
|
||||
);
|
||||
|
||||
# You define site-wide feature defaults here; override them with
|
||||
# $GITWEB_CONFIG as necessary.
|
||||
our %feature = (
|
||||
@@ -365,6 +373,27 @@ our %feature = (
|
||||
'sub' => \&feature_patches,
|
||||
'override' => 0,
|
||||
'default' => [16]},
|
||||
|
||||
# Avatar support. When this feature is enabled, views such as
|
||||
# shortlog or commit will display an avatar associated with
|
||||
# the email of the committer(s) and/or author(s).
|
||||
|
||||
# Currently available providers are gravatar and picon.
|
||||
# If an unknown provider is specified, the feature is disabled.
|
||||
|
||||
# Gravatar depends on Digest::MD5.
|
||||
# Picon currently relies on the indiana.edu database.
|
||||
|
||||
# To enable system wide have in $GITWEB_CONFIG
|
||||
# $feature{'avatar'}{'default'} = ['<provider>'];
|
||||
# where <provider> is either gravatar or picon.
|
||||
# To have project specific config enable override in $GITWEB_CONFIG
|
||||
# $feature{'avatar'}{'override'} = 1;
|
||||
# and in project config gitweb.avatar = <provider>;
|
||||
'avatar' => {
|
||||
'sub' => \&feature_avatar,
|
||||
'override' => 0,
|
||||
'default' => ['']},
|
||||
);
|
||||
|
||||
sub gitweb_get_feature {
|
||||
@@ -433,6 +462,12 @@ sub feature_patches {
|
||||
return ($_[0]);
|
||||
}
|
||||
|
||||
sub feature_avatar {
|
||||
my @val = (git_get_project_config('avatar'));
|
||||
|
||||
return @val ? @val : @_;
|
||||
}
|
||||
|
||||
# checking HEAD file with -e is fragile if the repository was
|
||||
# initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
|
||||
# and then pruned.
|
||||
@@ -814,6 +849,19 @@ $git_dir = "$projectroot/$project" if $project;
|
||||
our @snapshot_fmts = gitweb_get_feature('snapshot');
|
||||
@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);
|
||||
|
||||
# check that the avatar feature is set to a known provider name,
|
||||
# and for each provider check if the dependencies are satisfied.
|
||||
# if the provider name is invalid or the dependencies are not met,
|
||||
# reset $git_avatar to the empty string.
|
||||
our ($git_avatar) = gitweb_get_feature('avatar');
|
||||
if ($git_avatar eq 'gravatar') {
|
||||
$git_avatar = '' unless (eval { require Digest::MD5; 1; });
|
||||
} elsif ($git_avatar eq 'picon') {
|
||||
# no dependencies
|
||||
} else {
|
||||
$git_avatar = '';
|
||||
}
|
||||
|
||||
# dispatch
|
||||
if (!defined $action) {
|
||||
if (defined $hash) {
|
||||
@@ -1469,6 +1517,82 @@ sub format_subject_html {
|
||||
}
|
||||
}
|
||||
|
||||
# Rather than recomputing the url for an email multiple times, we cache it
|
||||
# after the first hit. This gives a visible benefit in views where the avatar
|
||||
# for the same email is used repeatedly (e.g. shortlog).
|
||||
# The cache is shared by all avatar engines (currently gravatar only), which
|
||||
# are free to use it as preferred. Since only one avatar engine is used for any
|
||||
# given page, there's no risk for cache conflicts.
|
||||
our %avatar_cache = ();
|
||||
|
||||
# Compute the picon url for a given email, by using the picon search service over at
|
||||
# http://www.cs.indiana.edu/picons/search.html
|
||||
sub picon_url {
|
||||
my $email = lc shift;
|
||||
if (!$avatar_cache{$email}) {
|
||||
my ($user, $domain) = split('@', $email);
|
||||
$avatar_cache{$email} =
|
||||
"http://www.cs.indiana.edu/cgi-pub/kinzler/piconsearch.cgi/" .
|
||||
"$domain/$user/" .
|
||||
"users+domains+unknown/up/single";
|
||||
}
|
||||
return $avatar_cache{$email};
|
||||
}
|
||||
|
||||
# Compute the gravatar url for a given email, if it's not in the cache already.
|
||||
# Gravatar stores only the part of the URL before the size, since that's the
|
||||
# one computationally more expensive. This also allows reuse of the cache for
|
||||
# different sizes (for this particular engine).
|
||||
sub gravatar_url {
|
||||
my $email = lc shift;
|
||||
my $size = shift;
|
||||
$avatar_cache{$email} ||=
|
||||
"http://www.gravatar.com/avatar/" .
|
||||
Digest::MD5::md5_hex($email) . "?s=";
|
||||
return $avatar_cache{$email} . $size;
|
||||
}
|
||||
|
||||
# Insert an avatar for the given $email at the given $size if the feature
|
||||
# is enabled.
|
||||
sub git_get_avatar {
|
||||
my ($email, %opts) = @_;
|
||||
my $pre_white = ($opts{-pad_before} ? " " : "");
|
||||
my $post_white = ($opts{-pad_after} ? " " : "");
|
||||
$opts{-size} ||= 'default';
|
||||
my $size = $avatar_size{$opts{-size}} || $avatar_size{'default'};
|
||||
my $url = "";
|
||||
if ($git_avatar eq 'gravatar') {
|
||||
$url = gravatar_url($email, $size);
|
||||
} elsif ($git_avatar eq 'picon') {
|
||||
$url = picon_url($email);
|
||||
}
|
||||
# Other providers can be added by extending the if chain, defining $url
|
||||
# as needed. If no variant puts something in $url, we assume avatars
|
||||
# are completely disabled/unavailable.
|
||||
if ($url) {
|
||||
return $pre_white .
|
||||
"<img width=\"$size\" " .
|
||||
"class=\"avatar\" " .
|
||||
"src=\"$url\" " .
|
||||
"alt=\"\" " .
|
||||
"/>" . $post_white;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# format the author name of the given commit with the given tag
|
||||
# the author name is chopped and escaped according to the other
|
||||
# optional parameters (see chop_str).
|
||||
sub format_author_html {
|
||||
my $tag = shift;
|
||||
my $co = shift;
|
||||
my $author = chop_and_escape_str($co->{'author_name'}, @_);
|
||||
return "<$tag class=\"author\">" .
|
||||
git_get_avatar($co->{'author_email'}, -pad_after => 1) .
|
||||
$author . "</$tag>";
|
||||
}
|
||||
|
||||
# format git diff header line, i.e. "diff --(git|combined|cc) ..."
|
||||
sub format_git_diff_header_line {
|
||||
my $line = shift;
|
||||
@@ -2399,8 +2523,14 @@ sub parse_tag {
|
||||
$tag{'name'} = $1;
|
||||
} elsif ($line =~ m/^tagger (.*) ([0-9]+) (.*)$/) {
|
||||
$tag{'author'} = $1;
|
||||
$tag{'epoch'} = $2;
|
||||
$tag{'tz'} = $3;
|
||||
$tag{'author_epoch'} = $2;
|
||||
$tag{'author_tz'} = $3;
|
||||
if ($tag{'author'} =~ m/^([^<]+) <([^>]*)>/) {
|
||||
$tag{'author_name'} = $1;
|
||||
$tag{'author_email'} = $2;
|
||||
} else {
|
||||
$tag{'author_name'} = $tag{'author'};
|
||||
}
|
||||
} elsif ($line =~ m/--BEGIN/) {
|
||||
push @comment, $line;
|
||||
last;
|
||||
@@ -3214,21 +3344,54 @@ sub git_print_header_div {
|
||||
"\n</div>\n";
|
||||
}
|
||||
|
||||
sub git_print_authorship {
|
||||
my $co = shift;
|
||||
|
||||
my %ad = parse_date($co->{'author_epoch'}, $co->{'author_tz'});
|
||||
print "<div class=\"author_date\">" .
|
||||
esc_html($co->{'author_name'}) .
|
||||
" [$ad{'rfc2822'}";
|
||||
if ($ad{'hour_local'} < 6) {
|
||||
sub print_local_time {
|
||||
my %date = @_;
|
||||
if ($date{'hour_local'} < 6) {
|
||||
printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
|
||||
$ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
|
||||
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
|
||||
} else {
|
||||
printf(" (%02d:%02d %s)",
|
||||
$ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
|
||||
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
|
||||
}
|
||||
}
|
||||
|
||||
# Outputs the author name and date in long form
|
||||
sub git_print_authorship {
|
||||
my $co = shift;
|
||||
my %opts = @_;
|
||||
my $tag = $opts{-tag} || 'div';
|
||||
|
||||
my %ad = parse_date($co->{'author_epoch'}, $co->{'author_tz'});
|
||||
print "<$tag class=\"author_date\">" .
|
||||
esc_html($co->{'author_name'}) .
|
||||
" [$ad{'rfc2822'}";
|
||||
print_local_time(%ad) if ($opts{-localtime});
|
||||
print "]" . git_get_avatar($co->{'author_email'}, -pad_before => 1)
|
||||
. "</$tag>\n";
|
||||
}
|
||||
|
||||
# Outputs table rows containing the full author or committer information,
|
||||
# in the format expected for 'commit' view (& similia).
|
||||
# Parameters are a commit hash reference, followed by the list of people
|
||||
# to output information for. If the list is empty it defalts to both
|
||||
# author and committer.
|
||||
sub git_print_authorship_rows {
|
||||
my $co = shift;
|
||||
# too bad we can't use @people = @_ || ('author', 'committer')
|
||||
my @people = @_;
|
||||
@people = ('author', 'committer') unless @people;
|
||||
foreach my $who (@people) {
|
||||
my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"});
|
||||
print "<tr><td>$who</td><td>" . esc_html($co->{$who}) . "</td>" .
|
||||
"<td rowspan=\"2\">" .
|
||||
git_get_avatar($co->{"${who}_email"}, -size => 'double') .
|
||||
"</td></tr>\n" .
|
||||
"<tr>" .
|
||||
"<td></td><td> $wd{'rfc2822'}";
|
||||
print_local_time(%wd);
|
||||
print "</td>" .
|
||||
"</tr>\n";
|
||||
}
|
||||
print "]</div>\n";
|
||||
}
|
||||
|
||||
sub git_print_page_path {
|
||||
@@ -4142,11 +4305,9 @@ sub git_shortlog_body {
|
||||
print "<tr class=\"light\">\n";
|
||||
}
|
||||
$alternate ^= 1;
|
||||
my $author = chop_and_escape_str($co{'author_name'}, 10);
|
||||
# git_summary() used print "<td><i>$co{'age_string'}</i></td>\n" .
|
||||
print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
|
||||
"<td><i>" . $author . "</i></td>\n" .
|
||||
"<td>";
|
||||
format_author_html('td', \%co, 10) . "<td>";
|
||||
print format_subject_html($co{'title'}, $co{'title_short'},
|
||||
href(action=>"commit", hash=>$commit), $ref);
|
||||
print "</td>\n" .
|
||||
@@ -4193,11 +4354,9 @@ sub git_history_body {
|
||||
print "<tr class=\"light\">\n";
|
||||
}
|
||||
$alternate ^= 1;
|
||||
# shortlog uses chop_str($co{'author_name'}, 10)
|
||||
my $author = chop_and_escape_str($co{'author_name'}, 15, 3);
|
||||
print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
|
||||
"<td><i>" . $author . "</i></td>\n" .
|
||||
"<td>";
|
||||
# shortlog: format_author_html('td', \%co, 10)
|
||||
format_author_html('td', \%co, 15, 3) . "<td>";
|
||||
# originally git_history used chop_str($co{'title'}, 50)
|
||||
print format_subject_html($co{'title'}, $co{'title_short'},
|
||||
href(action=>"commit", hash=>$commit), $ref);
|
||||
@@ -4350,9 +4509,8 @@ sub git_search_grep_body {
|
||||
print "<tr class=\"light\">\n";
|
||||
}
|
||||
$alternate ^= 1;
|
||||
my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
|
||||
print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
|
||||
"<td><i>" . $author . "</i></td>\n" .
|
||||
format_author_html('td', \%co, 15, 5) .
|
||||
"<td>" .
|
||||
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
|
||||
-class => "list subject"},
|
||||
@@ -4586,11 +4744,7 @@ sub git_tag {
|
||||
$tag{'type'}) . "</td>\n" .
|
||||
"</tr>\n";
|
||||
if (defined($tag{'author'})) {
|
||||
my %ad = parse_date($tag{'epoch'}, $tag{'tz'});
|
||||
print "<tr><td>author</td><td>" . esc_html($tag{'author'}) . "</td></tr>\n";
|
||||
print "<tr><td></td><td>" . $ad{'rfc2822'} .
|
||||
sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) .
|
||||
"</td></tr>\n";
|
||||
git_print_authorship_rows(\%tag, 'author');
|
||||
}
|
||||
print "</table>\n\n" .
|
||||
"</div>\n";
|
||||
@@ -5094,9 +5248,9 @@ sub git_log {
|
||||
" | " .
|
||||
$cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree") .
|
||||
"<br/>\n" .
|
||||
"</div>\n" .
|
||||
"<i>" . esc_html($co{'author_name'}) . " [$ad{'rfc2822'}]</i><br/>\n" .
|
||||
"</div>\n";
|
||||
git_print_authorship(\%co, -tag => 'span');
|
||||
print "<br/>\n</div>\n";
|
||||
|
||||
print "<div class=\"log_body\">\n";
|
||||
git_print_log($co{'comment'}, -final_empty_line=> 1);
|
||||
@@ -5115,8 +5269,6 @@ sub git_commit {
|
||||
$hash ||= $hash_base || "HEAD";
|
||||
my %co = parse_commit($hash)
|
||||
or die_error(404, "Unknown commit object");
|
||||
my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
|
||||
my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});
|
||||
|
||||
my $parent = $co{'parent'};
|
||||
my $parents = $co{'parents'}; # listref
|
||||
@@ -5183,22 +5335,7 @@ sub git_commit {
|
||||
}
|
||||
print "<div class=\"title_text\">\n" .
|
||||
"<table class=\"object_header\">\n";
|
||||
print "<tr><td>author</td><td>" . esc_html($co{'author'}) . "</td></tr>\n".
|
||||
"<tr>" .
|
||||
"<td></td><td> $ad{'rfc2822'}";
|
||||
if ($ad{'hour_local'} < 6) {
|
||||
printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
|
||||
$ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
|
||||
} else {
|
||||
printf(" (%02d:%02d %s)",
|
||||
$ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
|
||||
}
|
||||
print "</td>" .
|
||||
"</tr>\n";
|
||||
print "<tr><td>committer</td><td>" . esc_html($co{'committer'}) . "</td></tr>\n";
|
||||
print "<tr><td></td><td> $cd{'rfc2822'}" .
|
||||
sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) .
|
||||
"</td></tr>\n";
|
||||
git_print_authorship_rows(\%co);
|
||||
print "<tr><td>commit</td><td class=\"sha1\">$co{'id'}</td></tr>\n";
|
||||
print "<tr>" .
|
||||
"<td>tree</td>" .
|
||||
@@ -5579,7 +5716,11 @@ sub git_commitdiff {
|
||||
git_header_html(undef, $expires);
|
||||
git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
|
||||
git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
|
||||
git_print_authorship(\%co);
|
||||
print "<div class=\"title_text\">\n" .
|
||||
"<table class=\"object_header\">\n";
|
||||
git_print_authorship_rows(\%co);
|
||||
print "</table>".
|
||||
"</div>\n";
|
||||
print "<div class=\"page_body\">\n";
|
||||
if (@{$co{'comment'}} > 1) {
|
||||
print "<div class=\"log\">\n";
|
||||
|
||||
150
grep.c
150
grep.c
@@ -1,5 +1,6 @@
|
||||
#include "cache.h"
|
||||
#include "grep.h"
|
||||
#include "userdiff.h"
|
||||
#include "xdiff-interface.h"
|
||||
|
||||
void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
|
||||
@@ -490,6 +491,17 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
||||
{
|
||||
int rest = eol - bol;
|
||||
|
||||
if (opt->pre_context || opt->post_context) {
|
||||
if (opt->last_shown == 0) {
|
||||
if (opt->show_hunk_mark)
|
||||
fputs("--\n", stdout);
|
||||
else
|
||||
opt->show_hunk_mark = 1;
|
||||
} else if (lno > opt->last_shown + 1)
|
||||
fputs("--\n", stdout);
|
||||
}
|
||||
opt->last_shown = lno;
|
||||
|
||||
if (opt->null_following_name)
|
||||
sign = '\0';
|
||||
if (opt->pathname)
|
||||
@@ -520,22 +532,95 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
||||
printf("%.*s\n", rest, bol);
|
||||
}
|
||||
|
||||
static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
|
||||
{
|
||||
xdemitconf_t *xecfg = opt->priv;
|
||||
if (xecfg && xecfg->find_func) {
|
||||
char buf[1];
|
||||
return xecfg->find_func(bol, eol - bol, buf, 1,
|
||||
xecfg->find_func_priv) >= 0;
|
||||
}
|
||||
|
||||
if (bol == eol)
|
||||
return 0;
|
||||
if (isalpha(*bol) || *bol == '_' || *bol == '$')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_funcname_line(struct grep_opt *opt, const char *name,
|
||||
char *buf, char *bol, unsigned lno)
|
||||
{
|
||||
while (bol > buf) {
|
||||
char *eol = --bol;
|
||||
|
||||
while (bol > buf && bol[-1] != '\n')
|
||||
bol--;
|
||||
lno--;
|
||||
|
||||
if (lno <= opt->last_shown)
|
||||
break;
|
||||
|
||||
if (match_funcname(opt, bol, eol)) {
|
||||
show_line(opt, bol, eol, name, lno, '=');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
|
||||
char *bol, unsigned lno)
|
||||
{
|
||||
unsigned cur = lno, from = 1, funcname_lno = 0;
|
||||
int funcname_needed = opt->funcname;
|
||||
|
||||
if (opt->pre_context < lno)
|
||||
from = lno - opt->pre_context;
|
||||
if (from <= opt->last_shown)
|
||||
from = opt->last_shown + 1;
|
||||
|
||||
/* Rewind. */
|
||||
while (bol > buf && cur > from) {
|
||||
char *eol = --bol;
|
||||
|
||||
while (bol > buf && bol[-1] != '\n')
|
||||
bol--;
|
||||
cur--;
|
||||
if (funcname_needed && match_funcname(opt, bol, eol)) {
|
||||
funcname_lno = cur;
|
||||
funcname_needed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to look even further back to find a function signature. */
|
||||
if (opt->funcname && funcname_needed)
|
||||
show_funcname_line(opt, name, buf, bol, cur);
|
||||
|
||||
/* Back forward. */
|
||||
while (cur < lno) {
|
||||
char *eol = bol, sign = (cur == funcname_lno) ? '=' : '-';
|
||||
|
||||
while (*eol != '\n')
|
||||
eol++;
|
||||
show_line(opt, bol, eol, name, cur, sign);
|
||||
bol = eol + 1;
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
|
||||
static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||
char *buf, unsigned long size, int collect_hits)
|
||||
{
|
||||
char *bol = buf;
|
||||
unsigned long left = size;
|
||||
unsigned lno = 1;
|
||||
struct pre_context_line {
|
||||
char *bol;
|
||||
char *eol;
|
||||
} *prev = NULL, *pcl;
|
||||
unsigned last_hit = 0;
|
||||
unsigned last_shown = 0;
|
||||
int binary_match_only = 0;
|
||||
const char *hunk_mark = "";
|
||||
unsigned count = 0;
|
||||
enum grep_context ctx = GREP_CONTEXT_HEAD;
|
||||
xdemitconf_t xecfg;
|
||||
|
||||
opt->last_shown = 0;
|
||||
|
||||
if (buffer_is_binary(buf, size)) {
|
||||
switch (opt->binary) {
|
||||
@@ -550,10 +635,16 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->pre_context)
|
||||
prev = xcalloc(opt->pre_context, sizeof(*prev));
|
||||
if (opt->pre_context || opt->post_context)
|
||||
hunk_mark = "--\n";
|
||||
memset(&xecfg, 0, sizeof(xecfg));
|
||||
if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
|
||||
!opt->name_only && !binary_match_only && !collect_hits) {
|
||||
struct userdiff_driver *drv = userdiff_find_by_path(name);
|
||||
if (drv && drv->funcname.pattern) {
|
||||
const struct userdiff_funcname *pe = &drv->funcname;
|
||||
xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
|
||||
opt->priv = &xecfg;
|
||||
}
|
||||
}
|
||||
|
||||
while (left) {
|
||||
char *eol, ch;
|
||||
@@ -601,45 +692,20 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||
* the context which is nonsense, but the user
|
||||
* deserves to get that ;-).
|
||||
*/
|
||||
if (opt->pre_context) {
|
||||
unsigned from;
|
||||
if (opt->pre_context < lno)
|
||||
from = lno - opt->pre_context;
|
||||
else
|
||||
from = 1;
|
||||
if (from <= last_shown)
|
||||
from = last_shown + 1;
|
||||
if (last_shown && from != last_shown + 1)
|
||||
fputs(hunk_mark, stdout);
|
||||
while (from < lno) {
|
||||
pcl = &prev[lno-from-1];
|
||||
show_line(opt, pcl->bol, pcl->eol,
|
||||
name, from, '-');
|
||||
from++;
|
||||
}
|
||||
last_shown = lno-1;
|
||||
}
|
||||
if (last_shown && lno != last_shown + 1)
|
||||
fputs(hunk_mark, stdout);
|
||||
if (opt->pre_context)
|
||||
show_pre_context(opt, name, buf, bol, lno);
|
||||
else if (opt->funcname)
|
||||
show_funcname_line(opt, name, buf, bol, lno);
|
||||
if (!opt->count)
|
||||
show_line(opt, bol, eol, name, lno, ':');
|
||||
last_shown = last_hit = lno;
|
||||
last_hit = lno;
|
||||
}
|
||||
else if (last_hit &&
|
||||
lno <= last_hit + opt->post_context) {
|
||||
/* If the last hit is within the post context,
|
||||
* we need to show this line.
|
||||
*/
|
||||
if (last_shown && lno != last_shown + 1)
|
||||
fputs(hunk_mark, stdout);
|
||||
show_line(opt, bol, eol, name, lno, '-');
|
||||
last_shown = lno;
|
||||
}
|
||||
if (opt->pre_context) {
|
||||
memmove(prev+1, prev,
|
||||
(opt->pre_context-1) * sizeof(*prev));
|
||||
prev->bol = bol;
|
||||
prev->eol = eol;
|
||||
}
|
||||
|
||||
next_line:
|
||||
@@ -650,7 +716,6 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||
lno++;
|
||||
}
|
||||
|
||||
free(prev);
|
||||
if (collect_hits)
|
||||
return 0;
|
||||
|
||||
@@ -662,6 +727,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
xdiff_clear_find_func(&xecfg);
|
||||
opt->priv = NULL;
|
||||
|
||||
/* NEEDSWORK:
|
||||
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
|
||||
* which feels mostly useless but sometimes useful. Maybe
|
||||
|
||||
4
grep.h
4
grep.h
@@ -79,11 +79,15 @@ struct grep_opt {
|
||||
int pathname;
|
||||
int null_following_name;
|
||||
int color;
|
||||
int funcname;
|
||||
char color_match[COLOR_MAXLEN];
|
||||
const char *color_external;
|
||||
int regflags;
|
||||
unsigned pre_context;
|
||||
unsigned post_context;
|
||||
unsigned last_shown;
|
||||
int show_hunk_mark;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
||||
|
||||
@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,
|
||||
int fd;
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die("Cannot open %s", path);
|
||||
die_errno("Cannot open '%s'", path);
|
||||
hash_fd(fd, type, write_object, vpath);
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,8 @@ static char *xml_entities(char *s)
|
||||
case '&':
|
||||
strbuf_addstr(&buf, "&");
|
||||
break;
|
||||
case 0:
|
||||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
48
http.c
48
http.c
@@ -33,6 +33,17 @@ static int curl_ftp_no_epsv;
|
||||
static const char *curl_http_proxy;
|
||||
static char *user_name, *user_pass;
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071700
|
||||
/* Use CURLOPT_KEYPASSWD as is */
|
||||
#elif LIBCURL_VERSION_NUM >= 0x070903
|
||||
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
|
||||
#else
|
||||
#define CURLOPT_KEYPASSWD CURLOPT_SSLCERTPASSWD
|
||||
#endif
|
||||
|
||||
static char *ssl_cert_password;
|
||||
static int ssl_cert_password_required;
|
||||
|
||||
static struct curl_slist *pragma_header;
|
||||
static struct curl_slist *no_pragma_header;
|
||||
|
||||
@@ -136,6 +147,11 @@ static int http_options(const char *var, const char *value, void *cb)
|
||||
#endif
|
||||
if (!strcmp("http.sslcainfo", var))
|
||||
return git_config_string(&ssl_cainfo, var, value);
|
||||
if (!strcmp("http.sslcertpasswordprotected", var)) {
|
||||
if (git_config_bool(var, value))
|
||||
ssl_cert_password_required = 1;
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_CURL_MULTI
|
||||
if (!strcmp("http.maxrequests", var)) {
|
||||
max_requests = git_config_int(var, value);
|
||||
@@ -174,6 +190,22 @@ static void init_curl_http_auth(CURL *result)
|
||||
}
|
||||
}
|
||||
|
||||
static int has_cert_password(void)
|
||||
{
|
||||
if (ssl_cert_password != NULL)
|
||||
return 1;
|
||||
if (ssl_cert == NULL || ssl_cert_password_required != 1)
|
||||
return 0;
|
||||
/* Only prompt the user once. */
|
||||
ssl_cert_password_required = -1;
|
||||
ssl_cert_password = getpass("Certificate Password: ");
|
||||
if (ssl_cert_password != NULL) {
|
||||
ssl_cert_password = xstrdup(ssl_cert_password);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CURL *get_curl_handle(void)
|
||||
{
|
||||
CURL *result = curl_easy_init();
|
||||
@@ -196,6 +228,8 @@ static CURL *get_curl_handle(void)
|
||||
|
||||
if (ssl_cert != NULL)
|
||||
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
|
||||
if (has_cert_password())
|
||||
curl_easy_setopt(result, CURLOPT_KEYPASSWD, ssl_cert_password);
|
||||
#if LIBCURL_VERSION_NUM >= 0x070903
|
||||
if (ssl_key != NULL)
|
||||
curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
|
||||
@@ -339,8 +373,13 @@ void http_init(struct remote *remote)
|
||||
if (getenv("GIT_CURL_FTP_NO_EPSV"))
|
||||
curl_ftp_no_epsv = 1;
|
||||
|
||||
if (remote && remote->url && remote->url[0])
|
||||
if (remote && remote->url && remote->url[0]) {
|
||||
http_auth_init(remote->url[0]);
|
||||
if (!ssl_cert_password_required &&
|
||||
getenv("GIT_SSL_CERT_PASSWORD_PROTECTED") &&
|
||||
!prefixcmp(remote->url[0], "https://"))
|
||||
ssl_cert_password_required = 1;
|
||||
}
|
||||
|
||||
#ifndef NO_CURL_EASY_DUPHANDLE
|
||||
curl_default = get_curl_handle();
|
||||
@@ -383,6 +422,13 @@ void http_cleanup(void)
|
||||
free((void *)curl_http_proxy);
|
||||
curl_http_proxy = NULL;
|
||||
}
|
||||
|
||||
if (ssl_cert_password != NULL) {
|
||||
memset(ssl_cert_password, 0, strlen(ssl_cert_password));
|
||||
free(ssl_cert_password);
|
||||
ssl_cert_password = NULL;
|
||||
}
|
||||
ssl_cert_password_required = 0;
|
||||
}
|
||||
|
||||
struct active_request_slot *get_active_slot(void)
|
||||
|
||||
21
index-pack.c
21
index-pack.c
@@ -143,7 +143,7 @@ static void *fill(int min)
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
die("early EOF");
|
||||
die("read error on input: %s", strerror(errno));
|
||||
die_errno("read error on input");
|
||||
}
|
||||
input_len += ret;
|
||||
if (from_stdin)
|
||||
@@ -178,13 +178,12 @@ static char *open_pack_file(char *pack_name)
|
||||
} else
|
||||
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
|
||||
if (output_fd < 0)
|
||||
die("unable to create %s: %s", pack_name, strerror(errno));
|
||||
die_errno("unable to create '%s'", pack_name);
|
||||
pack_fd = output_fd;
|
||||
} else {
|
||||
input_fd = open(pack_name, O_RDONLY);
|
||||
if (input_fd < 0)
|
||||
die("cannot open packfile '%s': %s",
|
||||
pack_name, strerror(errno));
|
||||
die_errno("cannot open packfile '%s'", pack_name);
|
||||
output_fd = -1;
|
||||
pack_fd = input_fd;
|
||||
}
|
||||
@@ -370,7 +369,7 @@ static void *get_data_from_pack(struct object_entry *obj)
|
||||
do {
|
||||
ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
|
||||
if (n < 0)
|
||||
die("cannot pread pack file: %s", strerror(errno));
|
||||
die_errno("cannot pread pack file");
|
||||
if (!n)
|
||||
die("premature end of pack file, %lu bytes missing",
|
||||
len - rdy);
|
||||
@@ -631,7 +630,7 @@ static void parse_pack_objects(unsigned char *sha1)
|
||||
|
||||
/* If input_fd is a file, we should have reached its end now. */
|
||||
if (fstat(input_fd, &st))
|
||||
die("cannot fstat packfile: %s", strerror(errno));
|
||||
die_errno("cannot fstat packfile");
|
||||
if (S_ISREG(st.st_mode) &&
|
||||
lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
|
||||
die("pack has junk at the end");
|
||||
@@ -788,7 +787,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
fsync_or_die(output_fd, curr_pack_name);
|
||||
err = close(output_fd);
|
||||
if (err)
|
||||
die("error while closing pack file: %s", strerror(errno));
|
||||
die_errno("error while closing pack file");
|
||||
}
|
||||
|
||||
if (keep_msg) {
|
||||
@@ -801,16 +800,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
|
||||
if (keep_fd < 0) {
|
||||
if (errno != EEXIST)
|
||||
die("cannot write keep file '%s' (%s)",
|
||||
keep_name, strerror(errno));
|
||||
die_errno("cannot write keep file '%s'",
|
||||
keep_name);
|
||||
} else {
|
||||
if (keep_msg_len > 0) {
|
||||
write_or_die(keep_fd, keep_msg, keep_msg_len);
|
||||
write_or_die(keep_fd, "\n", 1);
|
||||
}
|
||||
if (close(keep_fd) != 0)
|
||||
die("cannot close written keep file '%s' (%s)",
|
||||
keep_name, strerror(errno));
|
||||
die_errno("cannot close written keep file '%s'",
|
||||
keep_name);
|
||||
report = "keep";
|
||||
}
|
||||
}
|
||||
|
||||
10
ll-merge.c
10
ll-merge.c
@@ -55,7 +55,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
|
||||
|
||||
static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
||||
mmbuffer_t *result,
|
||||
const char *path_unused,
|
||||
const char *path,
|
||||
mmfile_t *orig,
|
||||
mmfile_t *src1, const char *name1,
|
||||
mmfile_t *src2, const char *name2,
|
||||
@@ -67,10 +67,10 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
||||
if (buffer_is_binary(orig->ptr, orig->size) ||
|
||||
buffer_is_binary(src1->ptr, src1->size) ||
|
||||
buffer_is_binary(src2->ptr, src2->size)) {
|
||||
warning("Cannot merge binary files: %s vs. %s\n",
|
||||
name1, name2);
|
||||
warning("Cannot merge binary files: %s (%s vs. %s)\n",
|
||||
path, name1, name2);
|
||||
return ll_binary_merge(drv_unused, result,
|
||||
path_unused,
|
||||
path,
|
||||
orig, src1, name1,
|
||||
src2, name2,
|
||||
virtual_ancestor);
|
||||
@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)
|
||||
strcpy(path, ".merge_file_XXXXXX");
|
||||
fd = xmkstemp(path);
|
||||
if (write_in_full(fd, src->ptr, src->size) != src->size)
|
||||
die("unable to write temp-file");
|
||||
die_errno("unable to write temp-file");
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -321,7 +321,8 @@ void show_log(struct rev_info *opt)
|
||||
}
|
||||
|
||||
/*
|
||||
* If use_terminator is set, add a newline at the end of the entry.
|
||||
* If use_terminator is set, we already handled any record termination
|
||||
* at the end of the last record.
|
||||
* Otherwise, add a diffopt.line_termination character before all
|
||||
* entries but the first. (IOW, as a separator between entries)
|
||||
*/
|
||||
|
||||
@@ -438,7 +438,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
|
||||
/* Ignore epipe */
|
||||
if (errno == EPIPE)
|
||||
break;
|
||||
die("merge-recursive: %s", strerror(errno));
|
||||
die_errno("merge-recursive");
|
||||
} else if (!ret) {
|
||||
die("merge-recursive: disk full?");
|
||||
}
|
||||
@@ -554,7 +554,7 @@ static void update_file_flags(struct merge_options *o,
|
||||
mode = 0666;
|
||||
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
|
||||
if (fd < 0)
|
||||
die("failed to open %s: %s", path, strerror(errno));
|
||||
die_errno("failed to open '%s'", path);
|
||||
flush_buffer(fd, buf, size);
|
||||
close(fd);
|
||||
} else if (S_ISLNK(mode)) {
|
||||
@@ -562,7 +562,7 @@ static void update_file_flags(struct merge_options *o,
|
||||
safe_create_leading_directories_const(path);
|
||||
unlink(path);
|
||||
if (symlink(lnk, path))
|
||||
die("failed to symlink %s: %s", path, strerror(errno));
|
||||
die_errno("failed to symlink '%s'", path);
|
||||
free(lnk);
|
||||
} else
|
||||
die("do not know what to do with %06o %s '%s'",
|
||||
@@ -622,8 +622,13 @@ static int merge_3way(struct merge_options *o,
|
||||
char *name1, *name2;
|
||||
int merge_status;
|
||||
|
||||
name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
|
||||
name2 = xstrdup(mkpath("%s:%s", branch2, b->path));
|
||||
if (strcmp(a->path, b->path)) {
|
||||
name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
|
||||
name2 = xstrdup(mkpath("%s:%s", branch2, b->path));
|
||||
} else {
|
||||
name1 = xstrdup(mkpath("%s", branch1));
|
||||
name2 = xstrdup(mkpath("%s", branch2));
|
||||
}
|
||||
|
||||
fill_mm(one->sha1, &orig);
|
||||
fill_mm(a->sha1, &src1);
|
||||
|
||||
2
mktag.c
2
mktag.c
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
|
||||
setup_git_directory();
|
||||
|
||||
if (strbuf_read(&buf, 0, 4096) < 0) {
|
||||
die("could not read from stdin");
|
||||
die_errno("could not read from stdin");
|
||||
}
|
||||
|
||||
/* Verify it for some basic sanity: it needs to start with
|
||||
|
||||
@@ -93,8 +93,7 @@ int pack_refs(unsigned int flags)
|
||||
LOCK_DIE_ON_ERROR);
|
||||
cbdata.refs_file = fdopen(fd, "w");
|
||||
if (!cbdata.refs_file)
|
||||
die("unable to create ref-pack file structure (%s)",
|
||||
strerror(errno));
|
||||
die_errno("unable to create ref-pack file structure");
|
||||
|
||||
/* perhaps other traits later as well */
|
||||
fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
|
||||
@@ -103,7 +102,7 @@ int pack_refs(unsigned int flags)
|
||||
if (ferror(cbdata.refs_file))
|
||||
die("failed to write ref-pack file");
|
||||
if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
|
||||
die("failed to write ref-pack file (%s)", strerror(errno));
|
||||
die_errno("failed to write ref-pack file");
|
||||
/*
|
||||
* Since the lock file was fdopen()'ed and then fclose()'ed above,
|
||||
* assign -1 to the lock file descriptor so that commit_lock_file()
|
||||
@@ -111,7 +110,7 @@ int pack_refs(unsigned int flags)
|
||||
*/
|
||||
packed.fd = -1;
|
||||
if (commit_lock_file(&packed) < 0)
|
||||
die("unable to overwrite old ref-pack file (%s)", strerror(errno));
|
||||
die_errno("unable to overwrite old ref-pack file");
|
||||
if (cbdata.flags & PACK_REFS_PRUNE)
|
||||
prune_refs(cbdata.ref_to_prune);
|
||||
return 0;
|
||||
|
||||
10
pack-write.c
10
pack-write.c
@@ -51,7 +51,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
|
||||
fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||
}
|
||||
if (fd < 0)
|
||||
die("unable to create %s: %s", index_name, strerror(errno));
|
||||
die_errno("unable to create '%s'", index_name);
|
||||
f = sha1fd(fd, index_name);
|
||||
|
||||
/* if last object's offset is >= 2^31 we should use index V2 */
|
||||
@@ -174,11 +174,11 @@ void fixup_pack_header_footer(int pack_fd,
|
||||
git_SHA1_Init(&new_sha1_ctx);
|
||||
|
||||
if (lseek(pack_fd, 0, SEEK_SET) != 0)
|
||||
die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
|
||||
die_errno("Failed seeking to start of '%s'", pack_name);
|
||||
if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
|
||||
die("Unable to reread header of %s: %s", pack_name, strerror(errno));
|
||||
die_errno("Unable to reread header of '%s'", pack_name);
|
||||
if (lseek(pack_fd, 0, SEEK_SET) != 0)
|
||||
die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
|
||||
die_errno("Failed seeking to start of '%s'", pack_name);
|
||||
git_SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));
|
||||
hdr.hdr_entries = htonl(object_count);
|
||||
git_SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));
|
||||
@@ -195,7 +195,7 @@ void fixup_pack_header_footer(int pack_fd,
|
||||
if (!n)
|
||||
break;
|
||||
if (n < 0)
|
||||
die("Failed to checksum %s: %s", pack_name, strerror(errno));
|
||||
die_errno("Failed to checksum '%s'", pack_name);
|
||||
git_SHA1_Update(&new_sha1_ctx, buf, n);
|
||||
|
||||
aligned_sz -= n;
|
||||
|
||||
@@ -28,7 +28,7 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
|
||||
}
|
||||
if (!ret)
|
||||
die("write error (disk full?)");
|
||||
die("write error (%s)", strerror(errno));
|
||||
die_errno("write error");
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ static void safe_read(int fd, void *buffer, unsigned size)
|
||||
{
|
||||
ssize_t ret = read_in_full(fd, buffer, size);
|
||||
if (ret < 0)
|
||||
die("read error (%s)", strerror(errno));
|
||||
die_errno("read error");
|
||||
else if (ret < size)
|
||||
die("The remote end hung up unexpectedly");
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat(path, &st))
|
||||
die("%s: unable to stat (%s)", path, strerror(errno));
|
||||
die_errno("unable to stat '%s'", path);
|
||||
return add_to_index(istate, path, &st, flags);
|
||||
}
|
||||
|
||||
@@ -1251,11 +1251,11 @@ int read_index_from(struct index_state *istate, const char *path)
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
die("index file open failed (%s)", strerror(errno));
|
||||
die_errno("index file open failed");
|
||||
}
|
||||
|
||||
if (fstat(fd, &st))
|
||||
die("cannot stat the open index (%s)", strerror(errno));
|
||||
die_errno("cannot stat the open index");
|
||||
|
||||
errno = EINVAL;
|
||||
mmap_size = xsize_t(st.st_size);
|
||||
@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)
|
||||
mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
if (mmap == MAP_FAILED)
|
||||
die("unable to map index file");
|
||||
die_errno("unable to map index file");
|
||||
|
||||
hdr = mmap;
|
||||
if (verify_hdr(hdr, mmap_size) < 0)
|
||||
|
||||
2
refs.c
2
refs.c
@@ -1418,7 +1418,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
logfile = git_path("logs/%s", ref);
|
||||
logfd = open(logfile, O_RDONLY, 0);
|
||||
if (logfd < 0)
|
||||
die("Unable to read log %s: %s", logfile, strerror(errno));
|
||||
die_errno("Unable to read log '%s'", logfile);
|
||||
fstat(logfd, &st);
|
||||
if (!st.st_size)
|
||||
die("Log %s is empty.", logfile);
|
||||
|
||||
2
remote.c
2
remote.c
@@ -1277,7 +1277,7 @@ struct ref *get_remote_ref(const struct ref *remote_refs, const char *name)
|
||||
|
||||
static struct ref *get_local_ref(const char *name)
|
||||
{
|
||||
if (!name)
|
||||
if (!name || name[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
if (!prefixcmp(name, "refs/"))
|
||||
|
||||
@@ -1077,6 +1077,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
||||
revs->show_all = 1;
|
||||
} else if (!strcmp(arg, "--remove-empty")) {
|
||||
revs->remove_empty_trees = 1;
|
||||
} else if (!strcmp(arg, "--merges")) {
|
||||
revs->merges_only = 1;
|
||||
} else if (!strcmp(arg, "--no-merges")) {
|
||||
revs->no_merges = 1;
|
||||
} else if (!strcmp(arg, "--boundary")) {
|
||||
@@ -1676,6 +1678,8 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
return commit_ignore;
|
||||
if (revs->no_merges && commit->parents && commit->parents->next)
|
||||
return commit_ignore;
|
||||
if (revs->merges_only && !(commit->parents && commit->parents->next))
|
||||
return commit_ignore;
|
||||
if (!commit_match(commit, revs))
|
||||
return commit_ignore;
|
||||
if (revs->prune && revs->dense) {
|
||||
|
||||
@@ -36,6 +36,7 @@ struct rev_info {
|
||||
unsigned int dense:1,
|
||||
prune:1,
|
||||
no_merges:1,
|
||||
merges_only:1,
|
||||
no_walk:1,
|
||||
show_all:1,
|
||||
remove_empty_trees:1,
|
||||
|
||||
@@ -101,8 +101,8 @@ int start_command(struct child_process *cmd)
|
||||
}
|
||||
|
||||
if (cmd->dir && chdir(cmd->dir))
|
||||
die("exec %s: cd to %s failed (%s)", cmd->argv[0],
|
||||
cmd->dir, strerror(errno));
|
||||
die_errno("exec '%s': cd to '%s' failed", cmd->argv[0],
|
||||
cmd->dir);
|
||||
if (cmd->env) {
|
||||
for (; *cmd->env; cmd->env++) {
|
||||
if (strchr(*cmd->env, '='))
|
||||
|
||||
18
setup.c
18
setup.c
@@ -81,7 +81,7 @@ void verify_filename(const char *prefix, const char *arg)
|
||||
if (errno == ENOENT)
|
||||
die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
|
||||
"Use '--' to separate paths from revisions", arg);
|
||||
die("'%s': %s", arg, strerror(errno));
|
||||
die_errno("failed to stat '%s'", arg);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,7 +103,7 @@ void verify_non_filename(const char *prefix, const char *arg)
|
||||
die("ambiguous argument '%s': both revision and filename\n"
|
||||
"Use '--' to separate filenames from revisions", arg);
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
die("'%s': %s", arg, strerror(errno));
|
||||
die_errno("failed to stat '%s'", arg);
|
||||
}
|
||||
|
||||
const char **get_pathspec(const char *prefix, const char **pathspec)
|
||||
@@ -257,7 +257,7 @@ const char *read_gitfile_gently(const char *path)
|
||||
return NULL;
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die("Error opening %s: %s", path, strerror(errno));
|
||||
die_errno("Error opening '%s'", path);
|
||||
buf = xmalloc(st.st_size + 1);
|
||||
len = read_in_full(fd, buf, st.st_size);
|
||||
close(fd);
|
||||
@@ -327,7 +327,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
return NULL;
|
||||
set_git_dir(make_absolute_path(gitdirenv));
|
||||
if (chdir(work_tree_env) < 0)
|
||||
die ("Could not chdir to %s", work_tree_env);
|
||||
die_errno ("Could not chdir to '%s'", work_tree_env);
|
||||
strcat(buffer, "/");
|
||||
return retval;
|
||||
}
|
||||
@@ -339,7 +339,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
}
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd)-1))
|
||||
die("Unable to read current working directory");
|
||||
die_errno("Unable to read current working directory");
|
||||
|
||||
ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
|
||||
if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
|
||||
@@ -382,14 +382,14 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
if (offset <= ceil_offset) {
|
||||
if (nongit_ok) {
|
||||
if (chdir(cwd))
|
||||
die("Cannot come back to cwd");
|
||||
die_errno("Cannot come back to cwd");
|
||||
*nongit_ok = 1;
|
||||
return NULL;
|
||||
}
|
||||
die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
}
|
||||
if (chdir(".."))
|
||||
die("Cannot change to %s/..: %s", cwd, strerror(errno));
|
||||
die_errno("Cannot change to '%s/..'", cwd);
|
||||
}
|
||||
|
||||
inside_git_dir = 0;
|
||||
@@ -493,10 +493,10 @@ const char *setup_git_directory(void)
|
||||
static char buffer[PATH_MAX + 1];
|
||||
char *rel;
|
||||
if (retval && chdir(retval))
|
||||
die ("Could not jump back into original cwd");
|
||||
die_errno ("Could not jump back into original cwd");
|
||||
rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
|
||||
if (rel && *rel && chdir(get_git_work_tree()))
|
||||
die ("Could not jump to working directory");
|
||||
die_errno ("Could not jump to working directory");
|
||||
return rel && *rel ? strcat(rel, "/") : NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2286,7 +2286,7 @@ static void close_sha1_file(int fd)
|
||||
if (fsync_object_files)
|
||||
fsync_or_die(fd, "sha1 file");
|
||||
if (close(fd) != 0)
|
||||
die("error when closing sha1 file (%s)", strerror(errno));
|
||||
die_errno("error when closing sha1 file");
|
||||
}
|
||||
|
||||
/* Size of directory component, including the ending '/' */
|
||||
|
||||
2
shell.c
2
shell.c
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
|
||||
while (devnull_fd >= 0 && devnull_fd <= 2)
|
||||
devnull_fd = dup(devnull_fd);
|
||||
if (devnull_fd == -1)
|
||||
die("opening /dev/null failed (%s)", strerror(errno));
|
||||
die_errno("opening /dev/null failed");
|
||||
close (devnull_fd);
|
||||
|
||||
/*
|
||||
|
||||
2
strbuf.c
2
strbuf.c
@@ -260,7 +260,7 @@ size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
|
||||
res = fread(sb->buf + sb->len, 1, size, f);
|
||||
if (res > 0)
|
||||
strbuf_setlen(sb, sb->len + res);
|
||||
else if (res < 0 && oldalloc == 0)
|
||||
else if (oldalloc == 0)
|
||||
strbuf_release(sb);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ Extras
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_success 'test --parseopt help output' '
|
||||
git rev-parse --parseopt -- -h 2> output.err <<EOF
|
||||
cat > optionspec << EOF
|
||||
some-command [options] <args>...
|
||||
|
||||
some-command does foo and bar!
|
||||
@@ -37,7 +36,47 @@ C? option C with an optional argument
|
||||
Extras
|
||||
extra1 line above used to cause a segfault but no longer does
|
||||
EOF
|
||||
|
||||
test_expect_success 'test --parseopt help output' '
|
||||
git rev-parse --parseopt -- -h 2> output.err < optionspec
|
||||
test_cmp expect.err output.err
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
set -- --foo --bar 'ham' -- 'arg'
|
||||
EOF
|
||||
|
||||
test_expect_success 'test --parseopt' '
|
||||
git rev-parse --parseopt -- --foo --bar=ham arg < optionspec > output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success 'test --parseopt with mixed options and arguments' '
|
||||
git rev-parse --parseopt -- --foo arg --bar=ham < optionspec > output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
set -- --foo -- 'arg' '--bar=ham'
|
||||
EOF
|
||||
|
||||
test_expect_success 'test --parseopt with --' '
|
||||
git rev-parse --parseopt -- --foo -- arg --bar=ham < optionspec > output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success 'test --parseopt --stop-at-non-option' '
|
||||
git rev-parse --parseopt --stop-at-non-option -- --foo arg --bar=ham < optionspec > output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
set -- --foo -- '--' 'arg' '--bar=ham'
|
||||
EOF
|
||||
|
||||
test_expect_success 'test --parseopt --keep-dashdash' '
|
||||
git rev-parse --parseopt --keep-dashdash -- --foo -- arg --bar=ham < optionspec > output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -54,8 +54,8 @@ test_expect_success 'rebase against master' '
|
||||
git rebase master'
|
||||
|
||||
test_expect_success 'rebase against master twice' '
|
||||
git rebase master 2>err &&
|
||||
grep "Current branch my-topic-branch is up to date" err
|
||||
git rebase master >out &&
|
||||
grep "Current branch my-topic-branch is up to date" out
|
||||
'
|
||||
|
||||
test_expect_success 'rebase against master twice with --force' '
|
||||
@@ -65,14 +65,14 @@ test_expect_success 'rebase against master twice with --force' '
|
||||
|
||||
test_expect_success 'rebase against master twice from another branch' '
|
||||
git checkout my-topic-branch^ &&
|
||||
git rebase master my-topic-branch 2>err &&
|
||||
grep "Current branch my-topic-branch is up to date" err
|
||||
git rebase master my-topic-branch >out &&
|
||||
grep "Current branch my-topic-branch is up to date" out
|
||||
'
|
||||
|
||||
test_expect_success 'rebase fast-forward to master' '
|
||||
git checkout my-topic-branch^ &&
|
||||
git rebase my-topic-branch 2>err &&
|
||||
grep "Fast-forwarded HEAD to my-topic-branch" err
|
||||
git rebase my-topic-branch >out &&
|
||||
grep "Fast-forwarded HEAD to my-topic-branch" out
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
@@ -126,4 +126,11 @@ test_expect_success 'Show verbose error when HEAD could not be detached' '
|
||||
grep "Untracked working tree file .B. would be overwritten" output.err
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -q is quiet' '
|
||||
rm B &&
|
||||
git checkout -b quiet topic &&
|
||||
git rebase -q master > output.out 2>&1 &&
|
||||
test ! -s output.out
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user