mirror of
https://github.com/git/git.git
synced 2026-04-02 04:50:12 +02:00
Merge commit 'mingw/master' into work/1.6.4
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +1,2 @@
|
||||
* whitespace=!indent,trail,space
|
||||
*.[ch] whitespace
|
||||
*.[ch] whitespace=indent,trail,space
|
||||
|
||||
@@ -84,7 +84,7 @@ endif
|
||||
#
|
||||
|
||||
ifdef ASCIIDOC8
|
||||
ASCIIDOC_EXTRA += -a asciidoc7compatible
|
||||
ASCIIDOC_EXTRA += -a asciidoc7compatible -a no-inline-literal
|
||||
endif
|
||||
ifdef DOCBOOK_XSL_172
|
||||
ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
|
||||
|
||||
38
Documentation/RelNotes-1.6.3.3.txt
Normal file
38
Documentation/RelNotes-1.6.3.3.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
GIT v1.6.3.3 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.3.2
|
||||
--------------------
|
||||
|
||||
* "git archive" running on Cygwin can get stuck in an infinite loop.
|
||||
|
||||
* "git daemon" did not correctly parse the initial line that carries
|
||||
virtual host request information.
|
||||
|
||||
* "git diff --textconv" leaked memory badly when the textconv filter
|
||||
errored out.
|
||||
|
||||
* The built-in regular expressions to pick function names to put on
|
||||
hunk header lines for java and objc were very inefficiently written.
|
||||
|
||||
* in certain error situations git-fetch (and git-clone) on Windows didn't
|
||||
detect connection abort and ended up waiting indefinitely.
|
||||
|
||||
* import-tars script (in contrib) did not import symbolic links correctly.
|
||||
|
||||
* http.c used CURLOPT_SSLKEY even on libcURL version 7.9.2, even though
|
||||
it was only available starting 7.9.3.
|
||||
|
||||
* low-level filelevel merge driver used return value from strdup()
|
||||
without checking if we ran out of memory.
|
||||
|
||||
* "git rebase -i" left stray closing parenthesis in its reflog message.
|
||||
|
||||
* "git remote show" did not show all the URLs associated with the named
|
||||
remote, even though "git remote -v" did. Made them consistent by
|
||||
making the former show all URLs.
|
||||
|
||||
* "whitespace" attribute that is set was meant to detect all errors known
|
||||
to git, but it told git to ignore trailing carriage-returns.
|
||||
|
||||
Includes other documentation fixes.
|
||||
36
Documentation/RelNotes-1.6.3.4.txt
Normal file
36
Documentation/RelNotes-1.6.3.4.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
GIT v1.6.3.4 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.3.3
|
||||
--------------------
|
||||
|
||||
* "git add --no-ignore-errors" did not override configured
|
||||
add.ignore-errors configuration.
|
||||
|
||||
* "git apply --whitespace=fix" did not fix trailing whitespace on an
|
||||
incomplete line.
|
||||
|
||||
* "git branch" opened too many commit objects unnecessarily.
|
||||
|
||||
* "git checkout -f $commit" with a path that is a file (or a symlink) in
|
||||
the work tree to a commit that has a directory at the path issued an
|
||||
unnecessary error message.
|
||||
|
||||
* "git diff -c/--cc" was very inefficient in coalescing the removed lines
|
||||
shared between parents.
|
||||
|
||||
* "git diff -c/--cc" showed removed lines at the beginning of a file
|
||||
incorrectly.
|
||||
|
||||
* "git remote show nickname" did not honor configured
|
||||
remote.nickname.uploadpack when inspecting the branches at the remote.
|
||||
|
||||
* "git request-pull" when talking to the terminal for a preview
|
||||
showed some of the output in the pager.
|
||||
|
||||
* "git request-pull start nickname [end]" did not honor configured
|
||||
remote.nickname.uploadpack when it ran git-ls-remote against the remote
|
||||
repository to learn the current tip of branches.
|
||||
|
||||
Includes other documentation updates and minor fixes.
|
||||
|
||||
@@ -22,13 +22,6 @@ branch pointed at by its HEAD, gets a large warning. You can choose what
|
||||
should happen upon such a push by setting the configuration variable
|
||||
receive.denyDeleteCurrent in the receiving repository.
|
||||
|
||||
When the user does not tell "git push" what to push, it has always
|
||||
pushed matching refs. For some people it is unexpected, and a new
|
||||
configuration variable push.default has been introduced to allow
|
||||
changing a different default behaviour. To advertise the new feature,
|
||||
a big warning is issued if this is not configured and a git push without
|
||||
arguments is attempted.
|
||||
|
||||
|
||||
Updates since v1.6.3
|
||||
--------------------
|
||||
@@ -38,26 +31,67 @@ Updates since v1.6.3
|
||||
* gitweb Perl style clean-up.
|
||||
|
||||
* git-svn updates, including a new --authors-prog option to map author
|
||||
names by invoking an external program.
|
||||
names by invoking an external program, 'git svn reset' to unwind
|
||||
'git svn fetch', support for more than one branches, documenting
|
||||
of the useful --minimize-url feature, new "git svn gc" command, etc.
|
||||
|
||||
(portability)
|
||||
|
||||
* We feed iconv with "UTF-8" instead of "utf8"; the former is
|
||||
understood more widely.
|
||||
understood more widely. Similarly updated test scripts to use
|
||||
encoding names more widely understood (e.g. use "ISO8859-1" instead
|
||||
of "ISO-8859-1").
|
||||
|
||||
* Various portability fixes/workarounds for different vintages of
|
||||
SunOS, IRIX, and Windows.
|
||||
|
||||
* Git-over-ssh transport on Windows supports PuTTY plink and TortoisePlink.
|
||||
|
||||
(performance)
|
||||
|
||||
* Many repeated use of lstat() are optimized out in "checkout" codepath.
|
||||
|
||||
* git-status (and underlying git-diff-index --cached) are optimized
|
||||
to take advantage of cache-tree information in the index.
|
||||
|
||||
(usability, bells and whistles)
|
||||
|
||||
* "git add --edit" lets users edit the whole patch text to fine-tune what
|
||||
is added to the index.
|
||||
|
||||
* "git log --graph" draws graphs more compactly by using horizonal lines
|
||||
* "git am" accepts StGIT series file as its input.
|
||||
|
||||
* "git bisect skip" skips to a more randomly chosen place in the hope
|
||||
to avoid testing a commit that is too close to a commit that is
|
||||
already known to be untestable.
|
||||
|
||||
* "git cvsexportcommit" learned -k option to stop CVS keywords expansion
|
||||
|
||||
* "git fast-export" learned to handle history simplification more
|
||||
gracefully.
|
||||
|
||||
* "git fast-export" learned an option --tag-of-filtered-object to handle
|
||||
dangling tags resulting from history simplification more usefully.
|
||||
|
||||
* "git grep" learned -p option to show the location of the match using the
|
||||
same context hunk marker "git diff" uses.
|
||||
|
||||
* https transport can optionally be told that the used client
|
||||
certificate is password protected, in which case it asks the
|
||||
password only once.
|
||||
|
||||
* "git imap-send" is IPv6 aware.
|
||||
|
||||
* "git log --graph" draws graphs more compactly by using horizontal lines
|
||||
when able.
|
||||
|
||||
* "git log --decorate" shows shorter refnames by stripping well-known
|
||||
refs/* prefix.
|
||||
|
||||
* "git push $name" honors remote.$name.pushurl if present before
|
||||
using remote.$name.url. In other words, the URL used for fetching
|
||||
and pushing can be different.
|
||||
|
||||
* "git send-email" understands quoted aliases in .mailrc files (might
|
||||
have to be backported to 1.6.3.X).
|
||||
|
||||
@@ -69,10 +103,17 @@ Updates since v1.6.3
|
||||
* "add" and "update" subcommands to "git submodule" learned --reference
|
||||
option to use local clone with references.
|
||||
|
||||
* "git submodule update" learned --rebase option to update checked
|
||||
out submodules by rebasing the local changes.
|
||||
|
||||
* "gitweb" can optionally use gravatar to adorn author/committer names.
|
||||
|
||||
(developers)
|
||||
|
||||
* A major part of the "git bisect" wrapper has moved to C.
|
||||
|
||||
* Formatting with the new version of AsciiDoc 8.4.1 is now supported.
|
||||
|
||||
Fixes since v1.6.3
|
||||
------------------
|
||||
|
||||
@@ -82,12 +123,25 @@ release, unless otherwise noted.
|
||||
Here are fixes that this release has, but have not been backported to
|
||||
v1.6.3.X series.
|
||||
|
||||
* "git diff-tree -r -t" used to omit new or removed directories from
|
||||
the output. df533f3 (diff-tree -r -t: include added/removed
|
||||
directories in the output, 2009-06-13) may need to be cherry-picked
|
||||
to backport this fix.
|
||||
|
||||
* The way Git.pm sets up a Repository object was not friendly to callers
|
||||
that chdir around. It now internally records the repository location
|
||||
as an absolute path when autodetected.
|
||||
|
||||
---
|
||||
exec >/var/tmp/1
|
||||
echo O=$(git describe master)
|
||||
O=v1.6.3.1-168-g23807fa
|
||||
git shortlog --no-merges $O..master ^maint
|
||||
* Removing a section with "git config --remove-section", when its
|
||||
section header has a variable definition on the same line, lost
|
||||
that variable definition.
|
||||
|
||||
* "git rebase -p --onto" used to always leave side branches of a merge
|
||||
intact, even when both branches are subject to rewriting.
|
||||
|
||||
* "git repack" used to faithfully follow grafts and considered true
|
||||
parents recorded in the commit object unreachable from the commit.
|
||||
After such a repacking, you cannot remove grafts without corrupting
|
||||
the repository.
|
||||
|
||||
* "git send-email" did not detect erroneous loops in alias expansion.
|
||||
|
||||
@@ -17,6 +17,7 @@ caret=^
|
||||
startsb=[
|
||||
endsb=]
|
||||
tilde=~
|
||||
backtick=`
|
||||
|
||||
ifdef::backend-docbook[]
|
||||
[linkgit-inlinemacro]
|
||||
|
||||
@@ -49,7 +49,8 @@ There is also a case insensitive alternative `[section.subsection]` syntax.
|
||||
In this syntax, subsection names follow the same restrictions as for section
|
||||
names.
|
||||
|
||||
All the other lines are recognized as setting variables, in the form
|
||||
All the other lines (and the remainder of the line after the section
|
||||
header) are recognized as setting variables, in the form
|
||||
'name = value'. If there is no equal sign on the line, the entire line
|
||||
is taken as 'name' and the variable is recognized as boolean "true".
|
||||
The variable names are case-insensitive and only alphanumeric
|
||||
@@ -456,7 +457,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 +1046,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
|
||||
@@ -1319,6 +1328,9 @@ remote.<name>.url::
|
||||
The URL of a remote repository. See linkgit:git-fetch[1] or
|
||||
linkgit:git-push[1].
|
||||
|
||||
remote.<name>.pushurl::
|
||||
The push URL of a remote repository. See linkgit:git-push[1].
|
||||
|
||||
remote.<name>.proxy::
|
||||
For remotes that require curl (http, https and ftp), the URL to
|
||||
the proxy to use for that remote. Set to the empty string to
|
||||
@@ -1376,6 +1388,50 @@ rerere.enabled::
|
||||
default enabled if you create `rr-cache` directory under
|
||||
`$GIT_DIR`, but can be disabled by setting this option to false.
|
||||
|
||||
sendemail.identity::
|
||||
A configuration identity. When given, causes values in the
|
||||
'sendemail.<identity>' subsection to take precedence over
|
||||
values in the 'sendemail' section. The default identity is
|
||||
the value of 'sendemail.identity'.
|
||||
|
||||
sendemail.smtpencryption::
|
||||
See linkgit:git-send-email[1] for description. Note that this
|
||||
setting is not subject to the 'identity' mechanism.
|
||||
|
||||
sendemail.smtpssl::
|
||||
Deprecated alias for 'sendemail.smtpencryption = ssl'.
|
||||
|
||||
sendemail.<identity>.*::
|
||||
Identity-specific versions of the 'sendemail.*' parameters
|
||||
found below, taking precedence over those when the this
|
||||
identity is selected, through command-line or
|
||||
'sendemail.identity'.
|
||||
|
||||
sendemail.aliasesfile::
|
||||
sendemail.aliasfiletype::
|
||||
sendemail.bcc::
|
||||
sendemail.cc::
|
||||
sendemail.cccmd::
|
||||
sendemail.chainreplyto::
|
||||
sendemail.confirm::
|
||||
sendemail.envelopesender::
|
||||
sendemail.from::
|
||||
sendemail.multiedit::
|
||||
sendemail.signedoffbycc::
|
||||
sendemail.smtppass::
|
||||
sendemail.suppresscc::
|
||||
sendemail.suppressfrom::
|
||||
sendemail.to::
|
||||
sendemail.smtpserver::
|
||||
sendemail.smtpserverport::
|
||||
sendemail.smtpuser::
|
||||
sendemail.thread::
|
||||
sendemail.validate::
|
||||
See linkgit:git-send-email[1] for description.
|
||||
|
||||
sendemail.signedoffcc::
|
||||
Deprecated alias for 'sendemail.signedoffbycc'.
|
||||
|
||||
showbranch.default::
|
||||
The default set of branches for linkgit:git-show-branch[1].
|
||||
See linkgit:git-show-branch[1].
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
The output format from "git-diff-index", "git-diff-tree",
|
||||
Raw output format
|
||||
-----------------
|
||||
|
||||
The raw output format from "git-diff-index", "git-diff-tree",
|
||||
"git-diff-files" and "git diff --raw" are very similar.
|
||||
|
||||
These commands all compare two sets of things; what is
|
||||
@@ -16,6 +19,9 @@ git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]::
|
||||
git-diff-files [<pattern>...]::
|
||||
compares the index and the files on the filesystem.
|
||||
|
||||
The "git-diff-tree" command begins its ouput by printing the hash of
|
||||
what is being compared. After that, all the commands print one output
|
||||
line per changed file.
|
||||
|
||||
An output line is formatted this way:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -43,8 +43,7 @@ omit diff output for unmerged entries and just show "Unmerged".
|
||||
-q::
|
||||
Remain silent even on nonexistent files
|
||||
|
||||
Output format
|
||||
-------------
|
||||
|
||||
include::diff-format.txt[]
|
||||
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ include::diff-options.txt[]
|
||||
'git-diff-index' say that all non-checked-out files are up
|
||||
to date.
|
||||
|
||||
Output format
|
||||
-------------
|
||||
include::diff-format.txt[]
|
||||
|
||||
Operating Modes
|
||||
|
||||
@@ -159,8 +159,7 @@ HEAD commits it finds, which is even more interesting.
|
||||
|
||||
in case you care).
|
||||
|
||||
Output format
|
||||
-------------
|
||||
|
||||
include::diff-format.txt[]
|
||||
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ include::diff-options.txt[]
|
||||
the diff to the named paths (you can give directory
|
||||
names and get diff for all files under them).
|
||||
|
||||
Output format
|
||||
-------------
|
||||
|
||||
include::diff-format.txt[]
|
||||
|
||||
EXAMPLES
|
||||
|
||||
@@ -36,6 +36,17 @@ when encountering a signed tag. With 'strip', the tags will be made
|
||||
unsigned, with 'verbatim', they will be silently exported
|
||||
and with 'warn', they will be exported, but you will see a warning.
|
||||
|
||||
--tag-of-filtered-object=(abort|drop|rewrite)::
|
||||
Specify how to handle tags whose tagged objectis filtered out.
|
||||
Since revisions and files to export can be limited by path,
|
||||
tagged objects may be filtered completely.
|
||||
+
|
||||
When asking to 'abort' (which is the default), this program will die
|
||||
when encountering such a tag. With 'drop' it will omit such tags from
|
||||
the output. With 'rewrite', if the tagged object is a commit, it will
|
||||
rewrite the tag to tag an ancestor commit (via parent rewriting; see
|
||||
linkgit:git-rev-list[1])
|
||||
|
||||
-M::
|
||||
-C::
|
||||
Perform move and/or copy detection, as described in the
|
||||
@@ -71,6 +82,12 @@ marks the same across runs.
|
||||
allow that. So fake a tagger to be able to fast-import the
|
||||
output.
|
||||
|
||||
[git-rev-list-args...]::
|
||||
A list of arguments, acceptable to 'git-rev-parse' and
|
||||
'git-rev-list', that specifies the specific objects and references
|
||||
to export. For example, `master\~10..master` causes the
|
||||
current master reference to be exported along with all objects
|
||||
added since its 10th ancestor commit.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
@@ -10,7 +10,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git format-patch' [-k] [(-o|--output-directory) <dir> | --stdout]
|
||||
[--thread[=<style>]]
|
||||
[--no-thread | --thread[=<style>]]
|
||||
[(--attach|--inline)[=<boundary>] | --no-attach]
|
||||
[-s | --signoff]
|
||||
[-n | --numbered | -N | --no-numbered]
|
||||
@@ -124,17 +124,25 @@ include::diff-options.txt[]
|
||||
second part, with "Content-Disposition: inline".
|
||||
|
||||
--thread[=<style>]::
|
||||
Add In-Reply-To and References headers to make the second and
|
||||
subsequent mails appear as replies to the first. Also generates
|
||||
the Message-Id header to reference.
|
||||
--no-thread::
|
||||
Controls addition of In-Reply-To and References headers to
|
||||
make the second and subsequent mails appear as replies to the
|
||||
first. Also controls generation of the Message-Id header to
|
||||
reference.
|
||||
+
|
||||
The optional <style> argument can be either `shallow` or `deep`.
|
||||
'shallow' threading makes every mail a reply to the head of the
|
||||
series, where the head is chosen from the cover letter, the
|
||||
`\--in-reply-to`, and the first patch mail, in this order. 'deep'
|
||||
threading makes every mail a reply to the previous one. If not
|
||||
specified, defaults to the 'format.thread' configuration, or `shallow`
|
||||
if that is not set.
|
||||
threading makes every mail a reply to the previous one.
|
||||
+
|
||||
The default is --no-thread, unless the 'format.thread' configuration
|
||||
is set. If --thread is specified without a style, it defaults to the
|
||||
style specified by 'format.thread' if any, or else `shallow`.
|
||||
+
|
||||
Beware that the default for 'git send-email' is to thread emails
|
||||
itself. If you want 'git format-patch' to take care of hreading, you
|
||||
will want to ensure that threading is disabled for 'git send-email'.
|
||||
|
||||
--in-reply-to=Message-Id::
|
||||
Make the first mail (or all the mails with --no-thread) appear as a
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty]
|
||||
[--local] [--incremental] [--window=N] [--depth=N] [--all-progress]
|
||||
[--revs [--unpacked | --all]*] [--stdout | base-name] < object-list
|
||||
[--revs [--unpacked | --all]*] [--stdout | base-name]
|
||||
[--keep-true-parents] < object-list
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@@ -197,6 +198,10 @@ base-name::
|
||||
to force the version for the generated pack index, and to force
|
||||
64-bit index entries on objects located above the given offset.
|
||||
|
||||
--keep-true-parents::
|
||||
With this option, parents that are hidden by grafts are packed
|
||||
nevertheless.
|
||||
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
@@ -17,26 +17,6 @@ routines to parse files under $GIT_DIR/remotes/ and
|
||||
$GIT_DIR/branches/ and configuration variables that are related
|
||||
to fetching, pulling and pushing.
|
||||
|
||||
The primary entry points are:
|
||||
|
||||
get_remote_refs_for_fetch::
|
||||
Given the list of user-supplied `<repo> <refspec>...`,
|
||||
return the list of refs to fetch after canonicalizing
|
||||
them into `$GIT_DIR` relative paths
|
||||
(e.g. `refs/heads/foo`). When `<refspec>...` is empty
|
||||
the returned list of refs consists of the defaults
|
||||
for the given `<repo>`, if specified in
|
||||
`$GIT_DIR/remotes/`, `$GIT_DIR/branches/`, or `remote.*.fetch`
|
||||
configuration.
|
||||
|
||||
get_remote_refs_for_push::
|
||||
Given the list of user-supplied `<repo> <refspec>...`,
|
||||
return the list of refs to push in a form suitable to be
|
||||
fed to the 'git-send-pack' command. When `<refspec>...`
|
||||
is empty the returned list of refs consists of the
|
||||
defaults for the given `<repo>`, if specified in
|
||||
`$GIT_DIR/remotes/`.
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Junio C Hamano.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -23,7 +23,7 @@ on the initial manual merge, and applying previously recorded
|
||||
hand resolutions to their corresponding automerge results.
|
||||
|
||||
[NOTE]
|
||||
You need to set the configuration variable rerere.enabled to
|
||||
You need to set the configuration variable rerere.enabled in order to
|
||||
enable this command.
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ SYNOPSIS
|
||||
[ \--max-age=timestamp ]
|
||||
[ \--min-age=timestamp ]
|
||||
[ \--sparse ]
|
||||
[ \--merges ]
|
||||
[ \--no-merges ]
|
||||
[ \--first-parent ]
|
||||
[ \--remove-empty ]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -193,12 +193,12 @@ Automating
|
||||
- 'self' will avoid including the sender
|
||||
- 'cc' will avoid including anyone mentioned in Cc lines in the patch header
|
||||
except for self (use 'self' for that).
|
||||
- 'ccbody' will avoid including anyone mentioned in Cc lines in the
|
||||
- 'bodycc' will avoid including anyone mentioned in Cc lines in the
|
||||
patch body (commit message) except for self (use 'self' for that).
|
||||
- 'sob' will avoid including anyone mentioned in Signed-off-by lines except
|
||||
for self (use 'self' for that).
|
||||
- 'cccmd' will avoid running the --cc-cmd.
|
||||
- 'body' is equivalent to 'sob' + 'ccbody'
|
||||
- 'body' is equivalent to 'sob' + 'bodycc'
|
||||
- 'all' will suppress all auto cc values.
|
||||
--
|
||||
+
|
||||
@@ -212,11 +212,22 @@ specified, as well as 'body' if --no-signed-off-cc is specified.
|
||||
value; if that is unspecified, default to --no-suppress-from.
|
||||
|
||||
--[no-]thread::
|
||||
If this is set, the In-Reply-To header will be set on each email sent.
|
||||
If disabled with "--no-thread", no emails will have the In-Reply-To
|
||||
header set, unless specified with --in-reply-to.
|
||||
Default is the value of the 'sendemail.thread' configuration
|
||||
value; if that is unspecified, default to --thread.
|
||||
If this is set, the In-Reply-To and References headers will be
|
||||
added to each email sent. Whether each mail refers to the
|
||||
previous email (`deep` threading per 'git format-patch'
|
||||
wording) or to the first email (`shallow` threading) is
|
||||
governed by "--[no-]chain-reply-to".
|
||||
+
|
||||
If disabled with "--no-thread", those headers will not be added
|
||||
(unless specified with --in-reply-to). Default is the value of the
|
||||
'sendemail.thread' configuration value; if that is unspecified,
|
||||
default to --thread.
|
||||
+
|
||||
It is up to the user to ensure that no In-Reply-To header already
|
||||
exists when 'git send-email' is asked to add it (especially note that
|
||||
'git format-patch' can be configured to do the threading itself).
|
||||
Failure to do so may not produce the expected result in the
|
||||
recipient's MUA.
|
||||
|
||||
|
||||
Administering
|
||||
|
||||
@@ -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
|
||||
-----------
|
||||
@@ -24,7 +25,7 @@ The --exclude-existing form is a filter that does the inverse, it shows the
|
||||
refs from stdin that don't exist in the local repository.
|
||||
|
||||
Use of this utility is encouraged in favor of directly accessing files under
|
||||
in the `.git` directory.
|
||||
the `.git` directory.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
@@ -48,9 +49,9 @@ OPTIONS
|
||||
appended.
|
||||
|
||||
-s::
|
||||
--hash::
|
||||
--hash[=<n>]::
|
||||
|
||||
Only show the SHA1 hash, not the reference name. When also using
|
||||
Only show the SHA1 hash, not the reference name. When combined with
|
||||
--dereference the dereferenced tag will still be shown after the SHA1.
|
||||
|
||||
--verify::
|
||||
@@ -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}`
|
||||
|
||||
@@ -115,8 +115,9 @@ init::
|
||||
update::
|
||||
Update the registered submodules, i.e. clone missing submodules and
|
||||
checkout the commit specified in the index of the containing repository.
|
||||
This will make the submodules HEAD be detached unless '--rebase' is
|
||||
specified or the key `submodule.$name.update` is set to `rebase`.
|
||||
This will make the submodules HEAD be detached unless '--rebase' or
|
||||
'--merge' is specified or the key `submodule.$name.update` is set to
|
||||
`rebase` or `merge`.
|
||||
+
|
||||
If the submodule is not yet initialized, and you just want to use the
|
||||
setting as stored in .gitmodules, you can automatically initialize the
|
||||
@@ -140,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
|
||||
@@ -180,6 +182,16 @@ OPTIONS
|
||||
This option is only valid for the update command.
|
||||
Don't fetch new objects from the remote site.
|
||||
|
||||
--merge::
|
||||
This option is only valid for the update command.
|
||||
Merge the commit recorded in the superproject into the current branch
|
||||
of the submodule. If this option is given, the submodule's HEAD will
|
||||
not be detached. If a merge failure prevents this process, you will
|
||||
have to resolve the resulting conflicts within the submodule with the
|
||||
usual conflict resolution tools.
|
||||
If the key `submodule.$name.update` is set to `merge`, this option is
|
||||
implicit.
|
||||
|
||||
--rebase::
|
||||
This option is only valid for the update command.
|
||||
Rebase the current branch onto the commit recorded in the
|
||||
|
||||
@@ -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
|
||||
@@ -89,6 +80,17 @@ COMMANDS
|
||||
When passed to 'init' or 'clone' this regular expression will
|
||||
be preserved as a config key. See 'fetch' for a description
|
||||
of '--ignore-paths'.
|
||||
--no-minimize-url;;
|
||||
When tracking multiple directories (using --stdlayout,
|
||||
--branches, or --tags options), git svn will attempt to connect
|
||||
to the root (or highest allowed level) of the Subversion
|
||||
repository. This default allows better tracking of history if
|
||||
entire projects are moved within a repository, but may cause
|
||||
issues on repositories where read access restrictions are in
|
||||
place. Passing '--no-minimize-url' will allow git svn to
|
||||
accept URLs as-is without attempting to connect to a higher
|
||||
level directory. This option is off by default when only
|
||||
one URL/branch is tracked (it would do little good).
|
||||
|
||||
'fetch'::
|
||||
Fetch unfetched revisions from the Subversion remote we are
|
||||
@@ -98,12 +100,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 +118,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 +158,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 +188,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 +201,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 +225,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 +250,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 +278,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 +286,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 +307,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 +322,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 +349,170 @@ Any other arguments are passed directly to 'git-log'
|
||||
Shows the Subversion externals. Use -r/--revision to specify a
|
||||
specific revision.
|
||||
|
||||
--
|
||||
'gc'::
|
||||
Compress $GIT_DIR/svn/<refname>/unhandled.log files in .git/svn
|
||||
and remove $GIT_DIR/svn/<refname>index files in .git/svn.
|
||||
|
||||
'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 +521,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 +564,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 +604,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 +637,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 +668,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 +687,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 +696,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.
|
||||
@@ -623,14 +704,14 @@ pulled or merged from. This is because the author favored
|
||||
If you use `git svn set-tree A..B` to commit several diffs and you do
|
||||
not have the latest remotes/git-svn merged into my-branch, you should
|
||||
use `git svn rebase` to update your work branch instead of `git pull` or
|
||||
`git merge`. `pull`/`merge' can cause non-linear history to be flattened
|
||||
`git merge`. `pull`/`merge` can cause non-linear history to be flattened
|
||||
when committing into SVN, which can lead to merge commits reversing
|
||||
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 +722,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 +750,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 +776,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 +797,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
|
||||
--------
|
||||
|
||||
@@ -43,9 +43,16 @@ unreleased) version of git, that is available from 'master'
|
||||
branch of the `git.git` repository.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v1.6.3.2/git.html[documentation for release 1.6.3.2]
|
||||
* link:v1.6.4/git.html[documentation for release 1.6.4]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.6.4.txt[1.6.4].
|
||||
|
||||
* link:v1.6.3.4/git.html[documentation for release 1.6.3.4]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.6.3.4.txt[1.6.3.4],
|
||||
link:RelNotes-1.6.3.3.txt[1.6.3.3],
|
||||
link:RelNotes-1.6.3.2.txt[1.6.3.2],
|
||||
link:RelNotes-1.6.3.1.txt[1.6.3.1],
|
||||
link:RelNotes-1.6.3.txt[1.6.3].
|
||||
|
||||
@@ -35,9 +35,11 @@ submodule.<name>.update::
|
||||
If 'checkout' (the default), the new commit specified in the
|
||||
superproject will be checked out in the submodule on a detached HEAD.
|
||||
If 'rebase', the current branch of the submodule will be rebased onto
|
||||
the commit specified in the superproject.
|
||||
the commit specified in the superproject. If 'merge', the commit
|
||||
specified in the superproject will be merged into the current branch
|
||||
in the submodule.
|
||||
This config option is overridden if 'git submodule update' is given
|
||||
the '--rebase' option.
|
||||
the '--merge' or '--rebase' options.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -201,6 +201,10 @@ endif::git-rev-list[]
|
||||
|
||||
Stop when a given path disappears from the tree.
|
||||
|
||||
--merges::
|
||||
|
||||
Print only merge commits.
|
||||
|
||||
--no-merges::
|
||||
|
||||
Do not print commits with more than one parent.
|
||||
|
||||
@@ -18,6 +18,10 @@ struct remote
|
||||
|
||||
An array of all of the url_nr URLs configured for the remote
|
||||
|
||||
`pushurl`::
|
||||
|
||||
An array of all of the pushurl_nr push URLs configured for the remote
|
||||
|
||||
`push`::
|
||||
|
||||
An array of refspecs configured for pushing, with
|
||||
|
||||
@@ -27,10 +27,13 @@ config file would appear like this:
|
||||
------------
|
||||
[remote "<name>"]
|
||||
url = <url>
|
||||
pushurl = <pushurl>
|
||||
push = <refspec>
|
||||
fetch = <refspec>
|
||||
------------
|
||||
|
||||
The `<pushurl>` is used for pushes only. It is optional and defaults
|
||||
to `<url>`.
|
||||
|
||||
Named file in `$GIT_DIR/remotes`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.3.GIT
|
||||
DEF_VER=v1.6.4
|
||||
|
||||
LF='
|
||||
'
|
||||
|
||||
62
Makefile
62
Makefile
@@ -61,6 +61,8 @@ all::
|
||||
#
|
||||
# Define NO_LIBGEN_H if you don't have libgen.h.
|
||||
#
|
||||
# Define NEEDS_LIBGEN if your libgen needs -lgen when linking
|
||||
#
|
||||
# Define NO_SYS_SELECT_H if you don't have sys/select.h.
|
||||
#
|
||||
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
||||
@@ -194,6 +196,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 +727,8 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
NO_EXTERNAL_GREP = YesPlease
|
||||
ifeq ($(uname_R),5.7)
|
||||
NEEDS_RESOLV = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
@@ -750,7 +756,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
|
||||
@@ -825,18 +831,31 @@ ifeq ($(uname_S),GNU)
|
||||
NO_STRLCPY=YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),IRIX)
|
||||
NO_SETENV = YesPlease
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MMAP = YesPlease
|
||||
NO_EXTERNAL_GREP = UnfortunatelyYes
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH = /usr/gnu/bin/bash
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),IRIX64)
|
||||
NO_IPV6=YesPlease
|
||||
NO_SETENV=YesPlease
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR=YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_SOCKADDR_STORAGE=YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MMAP = YesPlease
|
||||
NO_EXTERNAL_GREP = UnfortunatelyYes
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH=/usr/gnu/bin/bash
|
||||
BASIC_CFLAGS += -DPATH_MAX=1024
|
||||
# for now, build 32-bit version
|
||||
BASIC_LDFLAGS += -L/usr/lib32
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),HP-UX)
|
||||
NO_IPV6=YesPlease
|
||||
@@ -883,9 +902,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))
|
||||
@@ -1014,6 +1034,9 @@ ifdef NEEDS_LIBICONV
|
||||
endif
|
||||
EXTLIBS += $(ICONV_LINK) -liconv
|
||||
endif
|
||||
ifdef NEEDS_LIBGEN
|
||||
EXTLIBS += -lgen
|
||||
endif
|
||||
ifdef NEEDS_SOCKET
|
||||
EXTLIBS += -lsocket
|
||||
endif
|
||||
@@ -1199,6 +1222,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
|
||||
@@ -1463,7 +1490,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)
|
||||
@@ -1632,15 +1659,16 @@ ifneq (,$X)
|
||||
endif
|
||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||
{ $(RM) "$$execdir/git-add$X" && \
|
||||
{ test "$$bindir/" = "$$execdir/" || \
|
||||
{ $(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);
|
||||
}
|
||||
|
||||
5
attr.c
5
attr.c
@@ -35,8 +35,7 @@ static struct git_attr *(git_attr_hash[HASHSIZE]);
|
||||
|
||||
static unsigned hash_name(const char *name, int namelen)
|
||||
{
|
||||
unsigned val = 0;
|
||||
unsigned char c;
|
||||
unsigned val = 0, c;
|
||||
|
||||
while (namelen--) {
|
||||
c = *name++;
|
||||
@@ -556,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.
|
||||
*/
|
||||
|
||||
2
base85.c
2
base85.c
@@ -91,7 +91,7 @@ void encode_85(char *buf, const unsigned char *data, int bytes)
|
||||
unsigned acc = 0;
|
||||
int cnt;
|
||||
for (cnt = 24; cnt >= 0; cnt -= 8) {
|
||||
int ch = *data++;
|
||||
unsigned ch = *data++;
|
||||
acc |= ch << cnt;
|
||||
if (--bytes == 0)
|
||||
break;
|
||||
|
||||
59
bisect.c
59
bisect.c
@@ -454,14 +454,14 @@ static int read_bisect_refs(void)
|
||||
return for_each_ref_in("refs/bisect/", register_ref, NULL);
|
||||
}
|
||||
|
||||
void read_bisect_paths(struct argv_array *array)
|
||||
static void read_bisect_paths(struct argv_array *array)
|
||||
{
|
||||
struct strbuf str = STRBUF_INIT;
|
||||
const char *filename = git_path("BISECT_NAMES");
|
||||
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);
|
||||
@@ -780,7 +807,7 @@ static void handle_bad_merge_base(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void handle_skipped_merge_base(const unsigned char *mb)
|
||||
static void handle_skipped_merge_base(const unsigned char *mb)
|
||||
{
|
||||
char *mb_hex = sha1_to_hex(mb);
|
||||
char *bad_hex = sha1_to_hex(current_bad_sha1);
|
||||
|
||||
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);
|
||||
|
||||
@@ -97,35 +97,6 @@ static void treat_gitlinks(const char **pathspec)
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_directory(struct dir_struct *dir, const char **pathspec,
|
||||
int ignored_too)
|
||||
{
|
||||
const char *path, *base;
|
||||
int baselen;
|
||||
|
||||
/* Set up the default git porcelain excludes */
|
||||
memset(dir, 0, sizeof(*dir));
|
||||
if (!ignored_too) {
|
||||
dir->flags |= DIR_COLLECT_IGNORED;
|
||||
setup_standard_excludes(dir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
baselen = common_prefix(pathspec);
|
||||
path = ".";
|
||||
base = "";
|
||||
if (baselen)
|
||||
path = base = xmemdupz(*pathspec, baselen);
|
||||
|
||||
/* Read the directory and prune it */
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
if (pathspec)
|
||||
prune_directory(dir, pathspec, baselen);
|
||||
}
|
||||
|
||||
static void refresh(int verbose, const char **pathspec)
|
||||
{
|
||||
char *seen;
|
||||
@@ -189,7 +160,7 @@ int interactive_add(int argc, const char **argv, const char *prefix)
|
||||
return status;
|
||||
}
|
||||
|
||||
int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
static int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
char *file = xstrdup(git_path("ADD_EDIT.patch"));
|
||||
const char *apply_argv[] = { "apply", "--recount", "--cached",
|
||||
@@ -220,7 +191,7 @@ 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.");
|
||||
|
||||
@@ -298,6 +269,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
int add_new_files;
|
||||
int require_pathspec;
|
||||
|
||||
git_config(add_config, NULL);
|
||||
|
||||
argc = parse_options(argc, argv, prefix, builtin_add_options,
|
||||
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
|
||||
if (patch_interactive)
|
||||
@@ -305,8 +278,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
if (add_interactive)
|
||||
exit(interactive_add(argc - 1, argv + 1, prefix));
|
||||
|
||||
git_config(add_config, NULL);
|
||||
|
||||
if (edit_interactive)
|
||||
return(edit_patch(argc, argv, prefix));
|
||||
argc--;
|
||||
@@ -343,9 +314,21 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
die("index file corrupt");
|
||||
treat_gitlinks(pathspec);
|
||||
|
||||
if (add_new_files)
|
||||
if (add_new_files) {
|
||||
int baselen;
|
||||
|
||||
/* Set up the default git porcelain excludes */
|
||||
memset(&dir, 0, sizeof(dir));
|
||||
if (!ignored_too) {
|
||||
dir.flags |= DIR_COLLECT_IGNORED;
|
||||
setup_standard_excludes(&dir);
|
||||
}
|
||||
|
||||
/* This picks up the paths that are not tracked */
|
||||
fill_directory(&dir, pathspec, ignored_too);
|
||||
baselen = fill_directory(&dir, pathspec);
|
||||
if (pathspec)
|
||||
prune_directory(&dir, pathspec, baselen);
|
||||
}
|
||||
|
||||
if (refresh_only) {
|
||||
refresh(verbose, pathspec);
|
||||
|
||||
@@ -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
|
||||
@@ -2614,7 +2614,7 @@ static int get_current_sha1(const char *path, unsigned char *sha1)
|
||||
static void build_fake_ancestor(struct patch *list, const char *filename)
|
||||
{
|
||||
struct patch *patch;
|
||||
struct index_state result = { 0 };
|
||||
struct index_state result = { NULL };
|
||||
int fd;
|
||||
|
||||
/* Once we start supporting the reverse patch, it may be
|
||||
@@ -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);
|
||||
|
||||
@@ -191,7 +191,7 @@ struct ref_item {
|
||||
|
||||
struct ref_list {
|
||||
struct rev_info revs;
|
||||
int index, alloc, maxwidth;
|
||||
int index, alloc, maxwidth, verbose, abbrev;
|
||||
struct ref_item *list;
|
||||
struct commit_list *with_commit;
|
||||
int kinds;
|
||||
@@ -240,21 +240,24 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
|
||||
if (ARRAY_SIZE(ref_kind) <= i)
|
||||
return 0;
|
||||
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!commit)
|
||||
return error("branch '%s' does not point at a commit", refname);
|
||||
|
||||
/* Filter with with_commit if specified */
|
||||
if (!is_descendant_of(commit, ref_list->with_commit))
|
||||
return 0;
|
||||
|
||||
/* Don't add types the caller doesn't want */
|
||||
if ((kind & ref_list->kinds) == 0)
|
||||
return 0;
|
||||
|
||||
if (merge_filter != NO_FILTER)
|
||||
add_pending_object(&ref_list->revs,
|
||||
(struct object *)commit, refname);
|
||||
commit = NULL;
|
||||
if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!commit)
|
||||
return error("branch '%s' does not point at a commit", refname);
|
||||
|
||||
/* Filter with with_commit if specified */
|
||||
if (!is_descendant_of(commit, ref_list->with_commit))
|
||||
return 0;
|
||||
|
||||
if (merge_filter != NO_FILTER)
|
||||
add_pending_object(&ref_list->revs,
|
||||
(struct object *)commit, refname);
|
||||
}
|
||||
|
||||
/* Resize buffer */
|
||||
if (ref_list->index >= ref_list->alloc) {
|
||||
@@ -415,18 +418,38 @@ static int calc_maxwidth(struct ref_list *refs)
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
static void show_detached(struct ref_list *ref_list)
|
||||
{
|
||||
struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
|
||||
|
||||
if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
|
||||
struct ref_item item;
|
||||
item.name = xstrdup("(no branch)");
|
||||
item.len = strlen(item.name);
|
||||
item.kind = REF_LOCAL_BRANCH;
|
||||
item.dest = NULL;
|
||||
item.commit = head_commit;
|
||||
if (item.len > ref_list->maxwidth)
|
||||
ref_list->maxwidth = item.len;
|
||||
print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
|
||||
free(item.name);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
|
||||
{
|
||||
int i;
|
||||
struct ref_list ref_list;
|
||||
struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
|
||||
|
||||
memset(&ref_list, 0, sizeof(ref_list));
|
||||
ref_list.kinds = kinds;
|
||||
ref_list.verbose = verbose;
|
||||
ref_list.abbrev = abbrev;
|
||||
ref_list.with_commit = with_commit;
|
||||
if (merge_filter != NO_FILTER)
|
||||
init_revisions(&ref_list.revs, NULL);
|
||||
for_each_ref(append_ref, &ref_list);
|
||||
for_each_rawref(append_ref, &ref_list);
|
||||
if (merge_filter != NO_FILTER) {
|
||||
struct commit *filter;
|
||||
filter = lookup_commit_reference_gently(merge_filter_ref, 0);
|
||||
@@ -442,19 +465,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
|
||||
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
|
||||
|
||||
detached = (detached && (kinds & REF_LOCAL_BRANCH));
|
||||
if (detached && head_commit &&
|
||||
is_descendant_of(head_commit, with_commit)) {
|
||||
struct ref_item item;
|
||||
item.name = xstrdup("(no branch)");
|
||||
item.len = strlen(item.name);
|
||||
item.kind = REF_LOCAL_BRANCH;
|
||||
item.dest = NULL;
|
||||
item.commit = head_commit;
|
||||
if (item.len > ref_list.maxwidth)
|
||||
ref_list.maxwidth = item.len;
|
||||
print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1, "");
|
||||
free(item.name);
|
||||
}
|
||||
if (detached)
|
||||
show_detached(&ref_list);
|
||||
|
||||
for (i = 0; i < ref_list.index; i++) {
|
||||
int current = !detached &&
|
||||
|
||||
@@ -33,7 +33,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
int ignored_only = 0, baselen = 0, config_set = 0, errors = 0;
|
||||
struct strbuf directory = STRBUF_INIT;
|
||||
struct dir_struct dir;
|
||||
const char *path, *base;
|
||||
static const char **pathspec;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *qname;
|
||||
@@ -78,16 +77,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
pathspec = get_pathspec(prefix, argv);
|
||||
read_cache();
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
baselen = common_prefix(pathspec);
|
||||
path = ".";
|
||||
base = "";
|
||||
if (baselen)
|
||||
path = base = xmemdupz(*pathspec, baselen);
|
||||
read_directory(&dir, path, base, baselen, pathspec);
|
||||
fill_directory(&dir, pathspec);
|
||||
|
||||
if (pathspec)
|
||||
seen = xmalloc(argc > 0 ? argc : 1);
|
||||
|
||||
@@ -141,7 +141,7 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
|
||||
if (is_bare) {
|
||||
struct strbuf result = STRBUF_INIT;
|
||||
strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
|
||||
dir = strbuf_detach(&result, 0);
|
||||
dir = strbuf_detach(&result, NULL);
|
||||
} else
|
||||
dir = xstrndup(start, end - start);
|
||||
/*
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ static const char *fast_export_usage[] = {
|
||||
};
|
||||
|
||||
static int progress;
|
||||
static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT;
|
||||
static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
|
||||
static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;
|
||||
static int fake_missing_tagger;
|
||||
|
||||
static int parse_opt_signed_tag_mode(const struct option *opt,
|
||||
@@ -42,6 +43,20 @@ static int parse_opt_signed_tag_mode(const struct option *opt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_opt_tag_of_filtered_mode(const struct option *opt,
|
||||
const char *arg, int unset)
|
||||
{
|
||||
if (unset || !strcmp(arg, "abort"))
|
||||
tag_of_filtered_mode = ABORT;
|
||||
else if (!strcmp(arg, "drop"))
|
||||
tag_of_filtered_mode = DROP;
|
||||
else if (!strcmp(arg, "rewrite"))
|
||||
tag_of_filtered_mode = REWRITE;
|
||||
else
|
||||
return error("Unknown tag-of-filtered mode: %s", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct decoration idnums;
|
||||
static uint32_t last_idnum;
|
||||
|
||||
@@ -119,7 +134,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();
|
||||
@@ -289,6 +304,23 @@ static void handle_tag(const char *name, struct tag *tag)
|
||||
char *buf;
|
||||
const char *tagger, *tagger_end, *message;
|
||||
size_t message_size = 0;
|
||||
struct object *tagged;
|
||||
int tagged_mark;
|
||||
struct commit *p;
|
||||
|
||||
/* Trees have no identifer in fast-export output, thus we have no way
|
||||
* to output tags of trees, tags of tags of trees, etc. Simply omit
|
||||
* such tags.
|
||||
*/
|
||||
tagged = tag->tagged;
|
||||
while (tagged->type == OBJ_TAG) {
|
||||
tagged = ((struct tag *)tagged)->tagged;
|
||||
}
|
||||
if (tagged->type == OBJ_TREE) {
|
||||
warning("Omitting tag %s,\nsince tags of trees (or tags of tags of trees, etc.) are not supported.",
|
||||
sha1_to_hex(tag->object.sha1));
|
||||
return;
|
||||
}
|
||||
|
||||
buf = read_sha1_file(tag->object.sha1, &type, &size);
|
||||
if (!buf)
|
||||
@@ -333,10 +365,45 @@ static void handle_tag(const char *name, struct tag *tag)
|
||||
}
|
||||
}
|
||||
|
||||
/* handle tag->tagged having been filtered out due to paths specified */
|
||||
tagged = tag->tagged;
|
||||
tagged_mark = get_object_mark(tagged);
|
||||
if (!tagged_mark) {
|
||||
switch(tag_of_filtered_mode) {
|
||||
case ABORT:
|
||||
die ("Tag %s tags unexported object; use "
|
||||
"--tag-of-filtered-object=<mode> to handle it.",
|
||||
sha1_to_hex(tag->object.sha1));
|
||||
case DROP:
|
||||
/* Ignore this tag altogether */
|
||||
return;
|
||||
case REWRITE:
|
||||
if (tagged->type != OBJ_COMMIT) {
|
||||
die ("Tag %s tags unexported %s!",
|
||||
sha1_to_hex(tag->object.sha1),
|
||||
typename(tagged->type));
|
||||
}
|
||||
p = (struct commit *)tagged;
|
||||
for (;;) {
|
||||
if (p->parents && p->parents->next)
|
||||
break;
|
||||
if (p->object.flags & UNINTERESTING)
|
||||
break;
|
||||
if (!(p->object.flags & TREESAME))
|
||||
break;
|
||||
if (!p->parents)
|
||||
die ("Can't find replacement commit for tag %s\n",
|
||||
sha1_to_hex(tag->object.sha1));
|
||||
p = p->parents->item;
|
||||
}
|
||||
tagged_mark = get_object_mark(&p->object);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prefixcmp(name, "refs/tags/"))
|
||||
name += 10;
|
||||
printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n",
|
||||
name, get_object_mark(tag->tagged),
|
||||
name, tagged_mark,
|
||||
(int)(tagger_end - tagger), tagger,
|
||||
tagger == tagger_end ? "" : "\n",
|
||||
(int)message_size, (int)message_size, message ? message : "");
|
||||
@@ -428,21 +495,27 @@ static void export_marks(char *file)
|
||||
uint32_t mark;
|
||||
struct object_decoration *deco = idnums.hash;
|
||||
FILE *f;
|
||||
int e = 0;
|
||||
|
||||
f = fopen(file, "w");
|
||||
if (!f)
|
||||
error("Unable to open marks file %s for writing", file);
|
||||
error("Unable to open marks file %s for writing.", file);
|
||||
|
||||
for (i = 0; i < idnums.size; i++) {
|
||||
if (deco->base && deco->base->type == 1) {
|
||||
mark = ptr_to_mark(deco->decoration);
|
||||
fprintf(f, ":%"PRIu32" %s\n", mark,
|
||||
sha1_to_hex(deco->base->sha1));
|
||||
if (fprintf(f, ":%"PRIu32" %s\n", mark,
|
||||
sha1_to_hex(deco->base->sha1)) < 0) {
|
||||
e = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
deco++;
|
||||
}
|
||||
|
||||
if (ferror(f) || fclose(f))
|
||||
e |= ferror(f);
|
||||
e |= fclose(f);
|
||||
if (e)
|
||||
error("Unable to write marks file %s.", file);
|
||||
}
|
||||
|
||||
@@ -451,7 +524,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;
|
||||
@@ -498,6 +571,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, "mode",
|
||||
"select handling of signed tags",
|
||||
parse_opt_signed_tag_mode),
|
||||
OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, "mode",
|
||||
"select handling of tags that tag filtered objects",
|
||||
parse_opt_tag_of_filtered_mode),
|
||||
OPT_STRING(0, "export-marks", &export_filename, "FILE",
|
||||
"Dump marks to this file"),
|
||||
OPT_STRING(0, "import-marks", &import_filename, "FILE",
|
||||
@@ -514,6 +590,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
init_revisions(&revs, prefix);
|
||||
revs.topo_order = 1;
|
||||
revs.show_source = 1;
|
||||
revs.rewrite_parents = 1;
|
||||
argc = setup_revisions(argc, argv, &revs, NULL);
|
||||
argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0);
|
||||
if (argc > 1)
|
||||
@@ -524,18 +603,13 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
|
||||
get_tags_and_duplicates(&revs.pending, &extra_refs);
|
||||
|
||||
revs.topo_order = 1;
|
||||
if (prepare_revision_walk(&revs))
|
||||
die("revision walk setup failed");
|
||||
revs.diffopt.format_callback = show_filemodify;
|
||||
DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
|
||||
while ((commit = get_revision(&revs))) {
|
||||
if (has_unshown_parent(commit)) {
|
||||
struct commit_list *parent = commit->parents;
|
||||
add_object_array(&commit->object, NULL, &commits);
|
||||
for (; parent; parent = parent->next)
|
||||
if (!parent->item->util)
|
||||
parent->item->util = commit->util;
|
||||
}
|
||||
else {
|
||||
handle_commit(commit, &revs);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -400,14 +400,14 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
|
||||
/*
|
||||
* We would want to bypass the object transfer altogether if
|
||||
* everything we are going to fetch already exists and connected
|
||||
* everything we are going to fetch already exists and is connected
|
||||
* locally.
|
||||
*
|
||||
* The refs we are going to fetch are in to_fetch (nr_heads in
|
||||
* total). If running
|
||||
* The refs we are going to fetch are in ref_map. If running
|
||||
*
|
||||
* $ git rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
|
||||
* $ git rev-list --objects --stdin --not --all
|
||||
*
|
||||
* (feeding all the refs in ref_map on its standard input)
|
||||
* does not error out, that means everything reachable from the
|
||||
* refs we are going to fetch exists and is connected to some of
|
||||
* our existing refs.
|
||||
@@ -416,8 +416,9 @@ static int quickfetch(struct ref *ref_map)
|
||||
{
|
||||
struct child_process revlist;
|
||||
struct ref *ref;
|
||||
char **argv;
|
||||
int i, err;
|
||||
int err;
|
||||
const char *argv[] = {"rev-list",
|
||||
"--quiet", "--objects", "--stdin", "--not", "--all", NULL};
|
||||
|
||||
/*
|
||||
* If we are deepening a shallow clone we already have these
|
||||
@@ -429,34 +430,46 @@ static int quickfetch(struct ref *ref_map)
|
||||
if (depth)
|
||||
return -1;
|
||||
|
||||
for (i = 0, ref = ref_map; ref; ref = ref->next)
|
||||
i++;
|
||||
if (!i)
|
||||
if (!ref_map)
|
||||
return 0;
|
||||
|
||||
argv = xmalloc(sizeof(*argv) * (i + 6));
|
||||
i = 0;
|
||||
argv[i++] = xstrdup("rev-list");
|
||||
argv[i++] = xstrdup("--quiet");
|
||||
argv[i++] = xstrdup("--objects");
|
||||
for (ref = ref_map; ref; ref = ref->next)
|
||||
argv[i++] = xstrdup(sha1_to_hex(ref->old_sha1));
|
||||
argv[i++] = xstrdup("--not");
|
||||
argv[i++] = xstrdup("--all");
|
||||
argv[i++] = NULL;
|
||||
|
||||
memset(&revlist, 0, sizeof(revlist));
|
||||
revlist.argv = (const char**)argv;
|
||||
revlist.argv = argv;
|
||||
revlist.git_cmd = 1;
|
||||
revlist.no_stdin = 1;
|
||||
revlist.no_stdout = 1;
|
||||
revlist.no_stderr = 1;
|
||||
err = run_command(&revlist);
|
||||
revlist.in = -1;
|
||||
|
||||
for (i = 0; argv[i]; i++)
|
||||
free(argv[i]);
|
||||
free(argv);
|
||||
return err;
|
||||
err = start_command(&revlist);
|
||||
if (err) {
|
||||
error("could not run rev-list");
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If rev-list --stdin encounters an unknown commit, it terminates,
|
||||
* which will cause SIGPIPE in the write loop below.
|
||||
*/
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
|
||||
for (ref = ref_map; ref; ref = ref->next) {
|
||||
if (write_in_full(revlist.in, sha1_to_hex(ref->old_sha1), 40) < 0 ||
|
||||
write_in_full(revlist.in, "\n", 1) < 0) {
|
||||
if (errno != EPIPE && errno != EINVAL)
|
||||
error("failed write to rev-list: %s", strerror(errno));
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (close(revlist.in)) {
|
||||
error("failed to close rev-list's stdin: %s", strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
return finish_command(&revlist) || err;
|
||||
}
|
||||
|
||||
static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -104,7 +104,7 @@ static int mark_object(struct object *obj, int type, void *data)
|
||||
|
||||
static void mark_object_reachable(struct object *obj)
|
||||
{
|
||||
mark_object(obj, OBJ_ANY, 0);
|
||||
mark_object(obj, OBJ_ANY, NULL);
|
||||
}
|
||||
|
||||
static int traverse_one_object(struct object *obj, struct object *parent)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -292,7 +292,7 @@ static int fsck_sha1(const unsigned char *sha1)
|
||||
fprintf(stderr, "Checking %s %s\n",
|
||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
|
||||
if (fsck_walk(obj, mark_used, 0))
|
||||
if (fsck_walk(obj, mark_used, NULL))
|
||||
objerror(obj, "broken links");
|
||||
if (fsck_object(obj, check_strict, fsck_error_func))
|
||||
return -1;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -394,7 +394,7 @@ static void get_html_page_path(struct strbuf *page_path, const char *page)
|
||||
* HTML.
|
||||
*/
|
||||
#ifndef open_html
|
||||
void open_html(const char *path)
|
||||
static void open_html(const char *path)
|
||||
{
|
||||
execl_git_cmd("web--browse", "-c", "help.browser", path, NULL);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -94,7 +94,7 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
|
||||
printf("Final output: %d %s\n", nr, stage);
|
||||
}
|
||||
|
||||
struct itimerval early_output_timer;
|
||||
static struct itimerval early_output_timer;
|
||||
|
||||
static void log_show_early(struct rev_info *revs, struct commit_list *list)
|
||||
{
|
||||
@@ -977,7 +977,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
strbuf_addch(&buf, '\n');
|
||||
}
|
||||
|
||||
rev.extra_headers = strbuf_detach(&buf, 0);
|
||||
rev.extra_headers = strbuf_detach(&buf, NULL);
|
||||
|
||||
if (start_number < 0)
|
||||
start_number = 1;
|
||||
@@ -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) {
|
||||
|
||||
@@ -161,12 +161,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
|
||||
|
||||
/* For cached/deleted files we don't need to even do the readdir */
|
||||
if (show_others || show_killed) {
|
||||
const char *path = ".", *base = "";
|
||||
int baselen = prefix_len;
|
||||
|
||||
if (baselen)
|
||||
path = base = prefix;
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
fill_directory(dir, pathspec);
|
||||
if (show_others)
|
||||
show_other_files(dir);
|
||||
if (show_killed)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
|
||||
|
||||
strbuf_addstr(&buf, "refs/heads/");
|
||||
strbuf_addstr(&buf, remote);
|
||||
resolve_ref(buf.buf, branch_head, 0, 0);
|
||||
resolve_ref(buf.buf, branch_head, 0, NULL);
|
||||
|
||||
if (!hashcmp(remote_head->sha1, branch_head)) {
|
||||
strbuf_addf(msg, "%s\t\tbranch '%s' of .\n",
|
||||
@@ -409,7 +409,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
|
||||
strbuf_addstr(&truname, "refs/heads/");
|
||||
strbuf_addstr(&truname, remote);
|
||||
strbuf_setlen(&truname, truname.len - len);
|
||||
if (resolve_ref(truname.buf, buf_sha, 0, 0)) {
|
||||
if (resolve_ref(truname.buf, buf_sha, 0, NULL)) {
|
||||
strbuf_addf(msg,
|
||||
"%s\t\tbranch '%s'%s of .\n",
|
||||
sha1_to_hex(remote_head->sha1),
|
||||
@@ -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);
|
||||
@@ -653,8 +649,7 @@ static void rehash_objects(void)
|
||||
|
||||
static unsigned name_hash(const char *name)
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned hash = 0;
|
||||
unsigned c, hash = 0;
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
@@ -1880,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;
|
||||
}
|
||||
@@ -2260,6 +2255,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
die("bad %s", arg);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--keep-true-parents")) {
|
||||
grafts_replace_parents = 0;
|
||||
continue;
|
||||
}
|
||||
usage(pack_usage);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -64,36 +64,11 @@ static void setup_push_tracking(void)
|
||||
add_refspec(refspec.buf);
|
||||
}
|
||||
|
||||
static const char *warn_unconfigured_push_msg[] = {
|
||||
"You did not specify any refspecs to push, and the current remote",
|
||||
"has not configured any push refspecs. The default action in this",
|
||||
"case is to push all matching refspecs, that is, all branches",
|
||||
"that exist both locally and remotely will be updated. This may",
|
||||
"not necessarily be what you want to happen.",
|
||||
"",
|
||||
"You can specify what action you want to take in this case, and",
|
||||
"avoid seeing this message again, by configuring 'push.default' to:",
|
||||
" 'nothing' : Do not push anything",
|
||||
" 'matching' : Push all matching branches (default)",
|
||||
" 'tracking' : Push the current branch to whatever it is tracking",
|
||||
" 'current' : Push the current branch"
|
||||
};
|
||||
|
||||
static void warn_unconfigured_push(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)
|
||||
warning("%s", warn_unconfigured_push_msg[i]);
|
||||
}
|
||||
|
||||
static void setup_default_push_refspecs(void)
|
||||
{
|
||||
git_config(git_default_config, NULL);
|
||||
switch (push_default) {
|
||||
case PUSH_DEFAULT_UNSPECIFIED:
|
||||
warn_unconfigured_push();
|
||||
/* fallthrough */
|
||||
|
||||
default:
|
||||
case PUSH_DEFAULT_MATCHING:
|
||||
add_refspec(":");
|
||||
break;
|
||||
@@ -117,6 +92,8 @@ static int do_push(const char *repo, int flags)
|
||||
{
|
||||
int i, errs;
|
||||
struct remote *remote = remote_get(repo);
|
||||
const char **url;
|
||||
int url_nr;
|
||||
|
||||
if (!remote) {
|
||||
if (repo)
|
||||
@@ -152,9 +129,16 @@ static int do_push(const char *repo, int flags)
|
||||
setup_default_push_refspecs();
|
||||
}
|
||||
errs = 0;
|
||||
for (i = 0; i < remote->url_nr; i++) {
|
||||
if (remote->pushurl_nr) {
|
||||
url = remote->pushurl;
|
||||
url_nr = remote->pushurl_nr;
|
||||
} else {
|
||||
url = remote->url;
|
||||
url_nr = remote->url_nr;
|
||||
}
|
||||
for (i = 0; i < url_nr; i++) {
|
||||
struct transport *transport =
|
||||
transport_get(remote, remote->url[i]);
|
||||
transport_get(remote, url[i]);
|
||||
int err;
|
||||
if (receivepack)
|
||||
transport_set_option(transport,
|
||||
@@ -163,14 +147,14 @@ static int do_push(const char *repo, int flags)
|
||||
transport_set_option(transport, TRANS_OPT_THIN, "yes");
|
||||
|
||||
if (flags & TRANSPORT_PUSH_VERBOSE)
|
||||
fprintf(stderr, "Pushing to %s\n", remote->url[i]);
|
||||
fprintf(stderr, "Pushing to %s\n", url[i]);
|
||||
err = transport_push(transport, refspec_nr, refspec, flags);
|
||||
err |= transport_disconnect(transport);
|
||||
|
||||
if (!err)
|
||||
continue;
|
||||
|
||||
error("failed to push some refs to '%s'", remote->url[i]);
|
||||
error("failed to push some refs to '%s'", url[i]);
|
||||
errs++;
|
||||
}
|
||||
return !!errs;
|
||||
@@ -191,6 +175,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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ static int rm(int argc, const char **argv)
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear_push_info(void *util, const char *string)
|
||||
static void clear_push_info(void *util, const char *string)
|
||||
{
|
||||
struct push_info *info = util;
|
||||
free(info->dest);
|
||||
@@ -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);
|
||||
@@ -815,7 +815,7 @@ struct show_info {
|
||||
int any_rebase;
|
||||
};
|
||||
|
||||
int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
|
||||
static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
struct show_info *info = cb_data;
|
||||
int n = strlen(item->string);
|
||||
@@ -825,7 +825,7 @@ int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_remote_info_item(struct string_list_item *item, void *cb_data)
|
||||
static int show_remote_info_item(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
struct show_info *info = cb_data;
|
||||
struct ref_states *states = info->states;
|
||||
@@ -852,7 +852,7 @@ int show_remote_info_item(struct string_list_item *item, void *cb_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
|
||||
static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
|
||||
{
|
||||
struct show_info *show_info = cb_data;
|
||||
struct ref_states *states = show_info->states;
|
||||
@@ -874,7 +874,7 @@ int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_local_info_item(struct string_list_item *item, void *cb_data)
|
||||
static int show_local_info_item(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
struct show_info *show_info = cb_data;
|
||||
struct branch_info *branch_info = item->util;
|
||||
@@ -906,7 +906,7 @@ int show_local_info_item(struct string_list_item *item, void *cb_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
|
||||
static int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
|
||||
{
|
||||
struct show_info *show_info = cb_data;
|
||||
struct push_info *push_info = push_item->util;
|
||||
@@ -935,7 +935,7 @@ static int cmp_string_with_push(const void *va, const void *vb)
|
||||
return cmp ? cmp : strcmp(a_push->dest, b_push->dest);
|
||||
}
|
||||
|
||||
int show_push_info_item(struct string_list_item *item, void *cb_data)
|
||||
static int show_push_info_item(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
struct show_info *show_info = cb_data;
|
||||
struct push_info *push_info = item->util;
|
||||
@@ -999,15 +999,25 @@ static int show(int argc, const char **argv)
|
||||
info.list = &info_list;
|
||||
for (; argc; argc--, argv++) {
|
||||
int i;
|
||||
const char **url;
|
||||
int url_nr;
|
||||
|
||||
get_remote_ref_states(*argv, &states, query_flag);
|
||||
|
||||
printf("* remote %s\n", *argv);
|
||||
if (states.remote->url_nr) {
|
||||
for (i=0; i < states.remote->url_nr; i++)
|
||||
printf(" URL: %s\n", states.remote->url[i]);
|
||||
} else
|
||||
printf(" URL: %s\n", "(no URL)");
|
||||
printf(" Fetch URL: %s\n", states.remote->url_nr > 0 ?
|
||||
states.remote->url[0] : "(no URL)");
|
||||
if (states.remote->pushurl_nr) {
|
||||
url = states.remote->pushurl;
|
||||
url_nr = states.remote->pushurl_nr;
|
||||
} else {
|
||||
url = states.remote->url;
|
||||
url_nr = states.remote->url_nr;
|
||||
}
|
||||
for (i=0; i < url_nr; i++)
|
||||
printf(" Push URL: %s\n", url[i]);
|
||||
if (!i)
|
||||
printf(" Push URL: %s\n", "(no URL)");
|
||||
if (no_query)
|
||||
printf(" HEAD branch: (not queried)\n");
|
||||
else if (!states.heads.nr)
|
||||
@@ -1187,7 +1197,7 @@ static int get_one_remote_for_update(struct remote *remote, void *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct remote_group {
|
||||
static struct remote_group {
|
||||
const char *name;
|
||||
struct string_list *list;
|
||||
} remote_group;
|
||||
@@ -1266,14 +1276,29 @@ 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;
|
||||
|
||||
if (remote->url_nr > 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < remote->url_nr; i++)
|
||||
string_list_append(remote->name, list)->util = (void *)remote->url[i];
|
||||
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) {
|
||||
url = remote->pushurl;
|
||||
url_nr = remote->pushurl_nr;
|
||||
} else {
|
||||
url = remote->url;
|
||||
url_nr = remote->url_nr;
|
||||
}
|
||||
for (i = 0; i < url_nr; i++)
|
||||
{
|
||||
strbuf_addf(&url_buf, "%s (push)", url[i]);
|
||||
string_list_append(remote->name, list)->util =
|
||||
strbuf_detach(&url_buf, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1281,7 +1306,10 @@ static int get_one_entry(struct remote *remote, void *priv)
|
||||
static int show_all(void)
|
||||
{
|
||||
struct string_list list = { NULL, 0, 0 };
|
||||
int result = for_each_remote(get_one_entry, &list);
|
||||
int result;
|
||||
|
||||
list.strdup_strings = 1;
|
||||
result = for_each_remote(get_one_entry, &list);
|
||||
|
||||
if (!result) {
|
||||
int i;
|
||||
@@ -1299,6 +1327,7 @@ static int show_all(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
string_list_clear(&list, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -158,7 +158,7 @@ struct obj_info {
|
||||
#define FLAG_WRITTEN (1u<<21)
|
||||
|
||||
static struct obj_info *obj_list;
|
||||
unsigned nr_objects;
|
||||
static unsigned nr_objects;
|
||||
|
||||
/*
|
||||
* Called only from check_object() after it verified this object
|
||||
@@ -200,7 +200,7 @@ static int check_object(struct object *obj, int type, void *data)
|
||||
|
||||
if (fsck_object(obj, 1, fsck_error_function))
|
||||
die("Error in object");
|
||||
if (!fsck_walk(obj, check_object, 0))
|
||||
if (!fsck_walk(obj, check_object, NULL))
|
||||
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
|
||||
write_cached_object(obj);
|
||||
return 1;
|
||||
@@ -210,7 +210,7 @@ static void write_rest(void)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < nr_objects; i++)
|
||||
check_object(obj_list[i].obj, OBJ_ANY, 0);
|
||||
check_object(obj_list[i].obj, OBJ_ANY, NULL);
|
||||
}
|
||||
|
||||
static void added_object(unsigned nr, enum object_type type,
|
||||
@@ -422,8 +422,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
|
||||
static void unpack_one(unsigned nr)
|
||||
{
|
||||
unsigned shift;
|
||||
unsigned char *pack, c;
|
||||
unsigned long size;
|
||||
unsigned char *pack;
|
||||
unsigned long size, c;
|
||||
enum object_type type;
|
||||
|
||||
obj_list[nr].offset = consumed_bytes;
|
||||
|
||||
@@ -80,16 +80,17 @@ static void error_clnt(const char *fmt, ...)
|
||||
die("sent error to the client: %s", buf);
|
||||
}
|
||||
|
||||
static void process_input(int child_fd, int band)
|
||||
static ssize_t process_input(int child_fd, int band)
|
||||
{
|
||||
char buf[16384];
|
||||
ssize_t sz = read(child_fd, buf, sizeof(buf));
|
||||
if (sz < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
error_clnt("read error: %s\n", strerror(errno));
|
||||
return;
|
||||
return sz;
|
||||
}
|
||||
send_sideband(1, band, buf, sz, LARGE_PACKET_MAX);
|
||||
return sz;
|
||||
}
|
||||
|
||||
int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
@@ -131,6 +132,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
|
||||
while (1) {
|
||||
struct pollfd pfd[2];
|
||||
ssize_t processed[2] = { 0, 0 };
|
||||
int status;
|
||||
|
||||
pfd[0].fd = fd1[0];
|
||||
@@ -147,12 +149,12 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
if (pfd[0].revents & POLLIN)
|
||||
/* Data stream ready */
|
||||
process_input(pfd[0].fd, 1);
|
||||
processed[0] = process_input(pfd[0].fd, 1);
|
||||
if (pfd[1].revents & POLLIN)
|
||||
/* Status stream ready */
|
||||
process_input(pfd[1].fd, 2);
|
||||
processed[1] = process_input(pfd[1].fd, 2);
|
||||
/* Always finish to read data when available */
|
||||
if ((pfd[0].revents | pfd[1].revents) & POLLIN)
|
||||
if (processed[0] || processed[1])
|
||||
continue;
|
||||
|
||||
if (waitpid(writer, &status, 0) < 0)
|
||||
|
||||
@@ -13,7 +13,7 @@ static const char write_tree_usage[] =
|
||||
|
||||
int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
{
|
||||
int missing_ok = 0, ret;
|
||||
int flags = 0, ret;
|
||||
const char *prefix = NULL;
|
||||
unsigned char sha1[20];
|
||||
const char *me = "git-write-tree";
|
||||
@@ -22,9 +22,15 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
while (1 < argc) {
|
||||
const char *arg = argv[1];
|
||||
if (!strcmp(arg, "--missing-ok"))
|
||||
missing_ok = 1;
|
||||
flags |= WRITE_TREE_MISSING_OK;
|
||||
else if (!prefixcmp(arg, "--prefix="))
|
||||
prefix = arg + 9;
|
||||
else if (!prefixcmp(arg, "--ignore-cache-tree"))
|
||||
/*
|
||||
* This is only useful for debugging, so I
|
||||
* do not bother documenting it.
|
||||
*/
|
||||
flags |= WRITE_TREE_IGNORE_CACHE_TREE;
|
||||
else
|
||||
usage(write_tree_usage);
|
||||
argc--; argv++;
|
||||
@@ -33,7 +39,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
if (argc > 2)
|
||||
die("too many options");
|
||||
|
||||
ret = write_cache_as_tree(sha1, missing_ok, prefix);
|
||||
ret = write_cache_as_tree(sha1, flags, prefix);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
printf("%s\n", sha1_to_hex(sha1));
|
||||
|
||||
47
cache-tree.c
47
cache-tree.c
@@ -329,7 +329,8 @@ static int update_one(struct cache_tree *it,
|
||||
entlen = pathlen - baselen;
|
||||
}
|
||||
if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))
|
||||
return error("invalid object %s", sha1_to_hex(sha1));
|
||||
return error("invalid object %06o %s for '%.*s'",
|
||||
mode, sha1_to_hex(sha1), entlen+baselen, path);
|
||||
|
||||
if (ce->ce_flags & CE_REMOVE)
|
||||
continue; /* entry being removed */
|
||||
@@ -514,6 +515,8 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
|
||||
|
||||
static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
|
||||
{
|
||||
if (!it)
|
||||
return NULL;
|
||||
while (*path) {
|
||||
const char *slash;
|
||||
struct cache_tree_sub *sub;
|
||||
@@ -538,28 +541,32 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
|
||||
return it;
|
||||
}
|
||||
|
||||
int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix)
|
||||
int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
|
||||
{
|
||||
int entries, was_valid, newfd;
|
||||
struct lock_file *lock_file;
|
||||
|
||||
/*
|
||||
* We can't free this memory, it becomes part of a linked list
|
||||
* parsed atexit()
|
||||
*/
|
||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
||||
|
||||
newfd = hold_locked_index(lock_file, 1);
|
||||
|
||||
entries = read_cache();
|
||||
if (entries < 0)
|
||||
return WRITE_TREE_UNREADABLE_INDEX;
|
||||
if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
|
||||
cache_tree_free(&(active_cache_tree));
|
||||
|
||||
if (!active_cache_tree)
|
||||
active_cache_tree = cache_tree();
|
||||
|
||||
was_valid = cache_tree_fully_valid(active_cache_tree);
|
||||
|
||||
if (!was_valid) {
|
||||
int missing_ok = flags & WRITE_TREE_MISSING_OK;
|
||||
|
||||
if (cache_tree_update(active_cache_tree,
|
||||
active_cache, active_nr,
|
||||
missing_ok, 0) < 0)
|
||||
@@ -625,3 +632,35 @@ void prime_cache_tree(struct cache_tree **it, struct tree *tree)
|
||||
*it = cache_tree();
|
||||
prime_cache_tree_rec(*it, tree);
|
||||
}
|
||||
|
||||
/*
|
||||
* find the cache_tree that corresponds to the current level without
|
||||
* exploding the full path into textual form. The root of the
|
||||
* cache tree is given as "root", and our current level is "info".
|
||||
* (1) When at root level, info->prev is NULL, so it is "root" itself.
|
||||
* (2) Otherwise, find the cache_tree that corresponds to one level
|
||||
* above us, and find ourselves in there.
|
||||
*/
|
||||
static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root,
|
||||
struct traverse_info *info)
|
||||
{
|
||||
struct cache_tree *our_parent;
|
||||
|
||||
if (!info->prev)
|
||||
return root;
|
||||
our_parent = find_cache_tree_from_traversal(root, info->prev);
|
||||
return cache_tree_find(our_parent, info->name.path);
|
||||
}
|
||||
|
||||
int cache_tree_matches_traversal(struct cache_tree *root,
|
||||
struct name_entry *ent,
|
||||
struct traverse_info *info)
|
||||
{
|
||||
struct cache_tree *it;
|
||||
|
||||
it = find_cache_tree_from_traversal(root, info);
|
||||
it = cache_tree_find(it, ent->path);
|
||||
if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1))
|
||||
return it->entry_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
10
cache-tree.h
10
cache-tree.h
@@ -2,6 +2,7 @@
|
||||
#define CACHE_TREE_H
|
||||
|
||||
#include "tree.h"
|
||||
#include "tree-walk.h"
|
||||
|
||||
struct cache_tree;
|
||||
struct cache_tree_sub {
|
||||
@@ -30,11 +31,18 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
|
||||
int cache_tree_fully_valid(struct cache_tree *);
|
||||
int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int);
|
||||
|
||||
/* bitmasks to write_cache_as_tree flags */
|
||||
#define WRITE_TREE_MISSING_OK 1
|
||||
#define WRITE_TREE_IGNORE_CACHE_TREE 2
|
||||
|
||||
/* error return codes */
|
||||
#define WRITE_TREE_UNREADABLE_INDEX (-1)
|
||||
#define WRITE_TREE_UNMERGED_INDEX (-2)
|
||||
#define WRITE_TREE_PREFIX_ERROR (-3)
|
||||
|
||||
int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
||||
int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix);
|
||||
void prime_cache_tree(struct cache_tree **, struct tree *);
|
||||
|
||||
extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
|
||||
|
||||
#endif
|
||||
|
||||
13
cache.h
13
cache.h
@@ -543,7 +543,6 @@ enum rebase_setup_type {
|
||||
};
|
||||
|
||||
enum push_default_type {
|
||||
PUSH_DEFAULT_UNSPECIFIED = -1,
|
||||
PUSH_DEFAULT_NOTHING = 0,
|
||||
PUSH_DEFAULT_MATCHING,
|
||||
PUSH_DEFAULT_TRACKING,
|
||||
@@ -561,6 +560,8 @@ enum object_creation_mode {
|
||||
|
||||
extern enum object_creation_mode object_creation_mode;
|
||||
|
||||
extern int grafts_replace_parents;
|
||||
|
||||
#define GIT_REPO_VERSION 0
|
||||
extern int repository_format_version;
|
||||
extern int check_repository_format(void);
|
||||
@@ -744,7 +745,17 @@ struct checkout {
|
||||
};
|
||||
|
||||
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
|
||||
|
||||
struct cache_def {
|
||||
char path[PATH_MAX + 1];
|
||||
int len;
|
||||
int flags;
|
||||
int track_flags;
|
||||
int prefix_len_stat_func;
|
||||
};
|
||||
|
||||
extern int has_symlink_leading_path(const char *name, int len);
|
||||
extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int);
|
||||
extern int has_symlink_or_noent_leading_path(const char *name, int len);
|
||||
extern int has_dirs_only_path(const char *name, int len, int prefix_len);
|
||||
extern void invalidate_lstat_cache(const char *name, int len);
|
||||
|
||||
@@ -80,6 +80,7 @@ struct lline {
|
||||
/* Lines surviving in the merge result */
|
||||
struct sline {
|
||||
struct lline *lost_head, **lost_tail;
|
||||
struct lline *next_lost;
|
||||
char *bol;
|
||||
int len;
|
||||
/* bit 0 up to (N-1) are on if the parent has this line (i.e.
|
||||
@@ -121,18 +122,12 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
|
||||
|
||||
/* Check to see if we can squash things */
|
||||
if (sline->lost_head) {
|
||||
struct lline *last_one = NULL;
|
||||
/* We cannot squash it with earlier one */
|
||||
for (lline = sline->lost_head;
|
||||
lline;
|
||||
lline = lline->next)
|
||||
if (lline->parent_map & this_mask)
|
||||
last_one = lline;
|
||||
lline = last_one ? last_one->next : sline->lost_head;
|
||||
lline = sline->next_lost;
|
||||
while (lline) {
|
||||
if (lline->len == len &&
|
||||
!memcmp(lline->line, line, len)) {
|
||||
lline->parent_map |= this_mask;
|
||||
sline->next_lost = lline->next;
|
||||
return;
|
||||
}
|
||||
lline = lline->next;
|
||||
@@ -147,6 +142,7 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
|
||||
lline->line[len] = 0;
|
||||
*sline->lost_tail = lline;
|
||||
sline->lost_tail = &lline->next;
|
||||
sline->next_lost = NULL;
|
||||
}
|
||||
|
||||
struct combine_diff_state {
|
||||
@@ -168,25 +164,28 @@ static void consume_line(void *state_, char *line, unsigned long len)
|
||||
&state->nb, &state->nn))
|
||||
return;
|
||||
state->lno = state->nb;
|
||||
if (!state->nb)
|
||||
/* @@ -1,2 +0,0 @@ to remove the
|
||||
* first two lines...
|
||||
*/
|
||||
state->nb = 1;
|
||||
if (state->nn == 0)
|
||||
if (state->nn == 0) {
|
||||
/* @@ -X,Y +N,0 @@ removed Y lines
|
||||
* that would have come *after* line N
|
||||
* in the result. Our lost buckets hang
|
||||
* to the line after the removed lines,
|
||||
*
|
||||
* Note that this is correct even when N == 0,
|
||||
* in which case the hunk removes the first
|
||||
* line in the file.
|
||||
*/
|
||||
state->lost_bucket = &state->sline[state->nb];
|
||||
else
|
||||
if (!state->nb)
|
||||
state->nb = 1;
|
||||
} else {
|
||||
state->lost_bucket = &state->sline[state->nb-1];
|
||||
}
|
||||
if (!state->sline[state->nb-1].p_lno)
|
||||
state->sline[state->nb-1].p_lno =
|
||||
xcalloc(state->num_parent,
|
||||
sizeof(unsigned long));
|
||||
state->sline[state->nb-1].p_lno[state->n] = state->ob;
|
||||
state->lost_bucket->next_lost = state->lost_bucket->lost_head;
|
||||
return;
|
||||
}
|
||||
if (!state->lost_bucket)
|
||||
@@ -746,7 +745,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);
|
||||
|
||||
|
||||
12
commit.c
12
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;
|
||||
@@ -266,7 +262,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
|
||||
bufptr[47] != '\n')
|
||||
return error("bad parents in commit %s", sha1_to_hex(item->object.sha1));
|
||||
bufptr += 48;
|
||||
if (graft)
|
||||
/*
|
||||
* The clone is shallow if nr_parent < 0, and we must
|
||||
* not traverse its real parents even when we unhide them.
|
||||
*/
|
||||
if (graft && (graft->nr_parent < 0 || grafts_replace_parents))
|
||||
continue;
|
||||
new_parent = lookup_commit(parent);
|
||||
if (new_parent)
|
||||
|
||||
@@ -93,6 +93,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
|
||||
|
||||
41
config.c
41
config.c
@@ -1174,7 +1174,9 @@ write_err_out:
|
||||
static int section_name_match (const char *buf, const char *name)
|
||||
{
|
||||
int i = 0, j = 0, dot = 0;
|
||||
for (; buf[i] && buf[i] != ']'; i++) {
|
||||
if (buf[i] != '[')
|
||||
return 0;
|
||||
for (i = 1; buf[i] && buf[i] != ']'; i++) {
|
||||
if (!dot && isspace(buf[i])) {
|
||||
dot = 1;
|
||||
if (name[j++] != '.')
|
||||
@@ -1195,7 +1197,17 @@ static int section_name_match (const char *buf, const char *name)
|
||||
if (buf[i] != name[j++])
|
||||
break;
|
||||
}
|
||||
return (buf[i] == ']' && name[j] == 0);
|
||||
if (buf[i] == ']' && name[j] == 0) {
|
||||
/*
|
||||
* We match, now just find the right length offset by
|
||||
* gobbling up any whitespace after it, as well
|
||||
*/
|
||||
i++;
|
||||
for (; buf[i] && isspace(buf[i]); i++)
|
||||
; /* do nothing */
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if new_name == NULL, the section is removed instead */
|
||||
@@ -1225,11 +1237,13 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
while (fgets(buf, sizeof(buf), config_file)) {
|
||||
int i;
|
||||
int length;
|
||||
char *output = buf;
|
||||
for (i = 0; buf[i] && isspace(buf[i]); i++)
|
||||
; /* do nothing */
|
||||
if (buf[i] == '[') {
|
||||
/* it's a section */
|
||||
if (section_name_match (&buf[i+1], old_name)) {
|
||||
int offset = section_name_match(&buf[i], old_name);
|
||||
if (offset > 0) {
|
||||
ret++;
|
||||
if (new_name == NULL) {
|
||||
remove = 1;
|
||||
@@ -1240,14 +1254,29 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
ret = write_error(lock->filename);
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
/*
|
||||
* We wrote out the new section, with
|
||||
* a newline, now skip the old
|
||||
* section's length
|
||||
*/
|
||||
output += offset + i;
|
||||
if (strlen(output) > 0) {
|
||||
/*
|
||||
* More content means there's
|
||||
* a declaration to put on the
|
||||
* next line; indent with a
|
||||
* tab
|
||||
*/
|
||||
output -= 1;
|
||||
output[0] = '\t';
|
||||
}
|
||||
}
|
||||
remove = 0;
|
||||
}
|
||||
if (remove)
|
||||
continue;
|
||||
length = strlen(buf);
|
||||
if (write_in_full(out_fd, buf, length) != length) {
|
||||
length = strlen(output);
|
||||
if (write_in_full(out_fd, output, length) != length) {
|
||||
ret = write_error(lock->filename);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ NO_LIBGEN_H=@NO_LIBGEN_H@
|
||||
NEEDS_LIBICONV=@NEEDS_LIBICONV@
|
||||
NEEDS_SOCKET=@NEEDS_SOCKET@
|
||||
NEEDS_RESOLV=@NEEDS_RESOLV@
|
||||
NEEDS_LIBGEN=@NEEDS_LIBGEN@
|
||||
NO_SYS_SELECT_H=@NO_SYS_SELECT_H@
|
||||
NO_D_INO_IN_DIRENT=@NO_D_INO_IN_DIRENT@
|
||||
NO_D_TYPE_IN_DIRENT=@NO_D_TYPE_IN_DIRENT@
|
||||
|
||||
21
configure.ac
21
configure.ac
@@ -342,9 +342,8 @@ GIT_STASH_FLAGS($OPENSSLDIR)
|
||||
AC_CHECK_LIB([crypto], [SHA1_Init],
|
||||
[NEEDS_SSL_WITH_CRYPTO=],
|
||||
[AC_CHECK_LIB([ssl], [SHA1_Init],
|
||||
[NEEDS_SSL_WITH_CRYPTO=YesPlease
|
||||
NEEDS_SSL_WITH_CRYPTO=],
|
||||
[NO_OPENSSL=YesPlease])])
|
||||
[NEEDS_SSL_WITH_CRYPTO=YesPlease],
|
||||
[NEEDS_SSL_WITH_CRYPTO= NO_OPENSSL=YesPlease])])
|
||||
|
||||
GIT_UNSTASH_FLAGS($OPENSSLDIR)
|
||||
|
||||
@@ -385,6 +384,8 @@ AC_SUBST(NO_EXPAT)
|
||||
# some Solaris installations).
|
||||
# Define NO_ICONV if neither libc nor libiconv support iconv.
|
||||
|
||||
if test -z "$NO_ICONV"; then
|
||||
|
||||
GIT_STASH_FLAGS($ICONVDIR)
|
||||
|
||||
AC_DEFUN([ICONVTEST_SRC], [
|
||||
@@ -431,6 +432,12 @@ GIT_UNSTASH_FLAGS($ICONVDIR)
|
||||
AC_SUBST(NEEDS_LIBICONV)
|
||||
AC_SUBST(NO_ICONV)
|
||||
|
||||
if test -n "$NO_ICONV"; then
|
||||
NEEDS_LIBICONV=
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# Define NO_DEFLATE_BOUND if deflateBound is missing from zlib.
|
||||
|
||||
@@ -471,12 +478,18 @@ test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket"
|
||||
# Define NEEDS_RESOLV if linking with -lnsl and/or -lsocket is not enough.
|
||||
# Notably on Solaris hstrerror resides in libresolv and on Solaris 7
|
||||
# inet_ntop and inet_pton additionally reside there.
|
||||
AC_CHECK_LIB([resolv], [hstrerror],
|
||||
AC_CHECK_LIB([c], [hstrerror],
|
||||
[NEEDS_RESOLV=],
|
||||
[NEEDS_RESOLV=YesPlease])
|
||||
AC_SUBST(NEEDS_RESOLV)
|
||||
test -n "$NEEDS_RESOLV" && LIBS="$LIBS -lresolv"
|
||||
|
||||
AC_CHECK_LIB([c], [basename],
|
||||
[NEEDS_LIBGEN=],
|
||||
[NEEDS_LIBGEN=YesPlease])
|
||||
AC_SUBST(NEEDS_LIBGEN)
|
||||
test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen"
|
||||
|
||||
## Checks for header files.
|
||||
AC_MSG_NOTICE([CHECKS for header files])
|
||||
#
|
||||
|
||||
@@ -464,7 +464,7 @@ static void git_proxy_connect(int fd[2], char *host)
|
||||
|
||||
#define MAX_CMD_LEN 1024
|
||||
|
||||
char *get_port(char *host)
|
||||
static char *get_port(char *host)
|
||||
{
|
||||
char *end;
|
||||
char *p = strchr(host, ':');
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
|
||||
# then a '$' will be shown next to the branch name.
|
||||
#
|
||||
# If you would like to see if there're untracked files, then you can
|
||||
# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
|
||||
# untracked files, then a '%' will be shown next to the branch name.
|
||||
#
|
||||
# To submit patches:
|
||||
#
|
||||
# *) Read Documentation/SubmittingPatches
|
||||
@@ -132,6 +136,7 @@ __git_ps1 ()
|
||||
local w
|
||||
local i
|
||||
local s
|
||||
local u
|
||||
local c
|
||||
|
||||
if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
|
||||
@@ -156,12 +161,18 @@ __git_ps1 ()
|
||||
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
|
||||
git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
|
||||
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
|
||||
u="%"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${1-}" ]; then
|
||||
printf "$1" "$c${b##refs/heads/}$w$i$s$r"
|
||||
printf "$1" "$c${b##refs/heads/}$w$i$s$u$r"
|
||||
else
|
||||
printf " (%s)" "$c${b##refs/heads/}$w$i$s$r"
|
||||
printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -1114,7 +1125,7 @@ _git_ls_tree ()
|
||||
__git_log_common_options="
|
||||
--not --all
|
||||
--branches --tags --remotes
|
||||
--first-parent --no-merges
|
||||
--first-parent --merges --no-merges
|
||||
--max-count=
|
||||
--max-age= --since= --after=
|
||||
--min-age= --until= --before=
|
||||
@@ -1165,7 +1176,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
|
||||
@@ -1299,7 +1310,7 @@ _git_rebase ()
|
||||
}
|
||||
|
||||
__git_send_email_confirm_options="always never auto cc compose"
|
||||
__git_send_email_suppresscc_options="author self cc ccbody sob cccmd body all"
|
||||
__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
|
||||
|
||||
_git_send_email ()
|
||||
{
|
||||
@@ -1357,11 +1368,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 +1469,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 +1516,7 @@ _git_config ()
|
||||
cur="${cur##*.}"
|
||||
__gitcomp "
|
||||
url proxy fetch push mirror skipDefaultUpdate
|
||||
receivepack uploadpack tagopt
|
||||
receivepack uploadpack tagopt pushurl
|
||||
" "$pfx" "$cur"
|
||||
return
|
||||
;;
|
||||
@@ -1522,6 +1534,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;
|
||||
|
||||
73
daemon.c
73
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[] = {
|
||||
@@ -453,7 +493,7 @@ static void parse_host_arg(char *extra_args, int buflen)
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
|
||||
gai = getaddrinfo(hostname, 0, &hints, &ai);
|
||||
gai = getaddrinfo(hostname, NULL, &hints, &ai);
|
||||
if (!gai) {
|
||||
struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
|
||||
|
||||
@@ -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;
|
||||
|
||||
5
delta.h
5
delta.h
@@ -90,12 +90,11 @@ static inline unsigned long get_delta_hdr_size(const unsigned char **datap,
|
||||
const unsigned char *top)
|
||||
{
|
||||
const unsigned char *data = *datap;
|
||||
unsigned char cmd;
|
||||
unsigned long size = 0;
|
||||
unsigned long cmd, size = 0;
|
||||
int i = 0;
|
||||
do {
|
||||
cmd = *data++;
|
||||
size |= (cmd & ~0x80) << i;
|
||||
size |= (cmd & 0x7f) << i;
|
||||
i += 7;
|
||||
} while (cmd & 0x80 && data < top);
|
||||
*datap = data;
|
||||
|
||||
@@ -446,6 +446,8 @@ int run_diff_index(struct rev_info *revs, int cached)
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.head_idx = 1;
|
||||
opts.index_only = cached;
|
||||
opts.diff_index_cached = (cached &&
|
||||
!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER));
|
||||
opts.merge = 1;
|
||||
opts.fn = oneway_diff;
|
||||
opts.unpack_data = revs;
|
||||
@@ -502,6 +504,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.head_idx = 1;
|
||||
opts.index_only = 1;
|
||||
opts.diff_index_cached = !DIFF_OPT_TST(opt, FIND_COPIES_HARDER);
|
||||
opts.merge = 1;
|
||||
opts.fn = oneway_diff;
|
||||
opts.unpack_data = &revs;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
113
dir.c
113
dir.c
@@ -14,12 +14,11 @@ struct path_simplify {
|
||||
const char *path;
|
||||
};
|
||||
|
||||
static int read_directory_recursive(struct dir_struct *dir,
|
||||
const char *path, const char *base, int baselen,
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, int len,
|
||||
int check_only, const struct path_simplify *simplify);
|
||||
static int get_dtype(struct dirent *de, const char *path);
|
||||
static int get_dtype(struct dirent *de, const char *path, int len);
|
||||
|
||||
int common_prefix(const char **pathspec)
|
||||
static int common_prefix(const char **pathspec)
|
||||
{
|
||||
const char *path, *slash, *next;
|
||||
int prefix;
|
||||
@@ -52,6 +51,26 @@ int common_prefix(const char **pathspec)
|
||||
return prefix;
|
||||
}
|
||||
|
||||
int fill_directory(struct dir_struct *dir, const char **pathspec)
|
||||
{
|
||||
const char *path;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
len = common_prefix(pathspec);
|
||||
path = "";
|
||||
|
||||
if (len)
|
||||
path = xmemdupz(*pathspec, len);
|
||||
|
||||
/* Read the directory and prune it */
|
||||
read_directory(dir, path, len, pathspec);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does 'match' match the given name?
|
||||
* A match is found if
|
||||
@@ -307,7 +326,7 @@ static int excluded_1(const char *pathname,
|
||||
|
||||
if (x->flags & EXC_FLAG_MUSTBEDIR) {
|
||||
if (*dtype == DT_UNKNOWN)
|
||||
*dtype = get_dtype(NULL, pathname);
|
||||
*dtype = get_dtype(NULL, pathname, pathlen);
|
||||
if (*dtype != DT_DIR)
|
||||
continue;
|
||||
}
|
||||
@@ -505,7 +524,7 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
|
||||
/* This is the "show_other_directories" case */
|
||||
if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
|
||||
return show_directory;
|
||||
if (!read_directory_recursive(dir, dirname, dirname, len, 1, simplify))
|
||||
if (!read_directory_recursive(dir, dirname, len, 1, simplify))
|
||||
return ignore_directory;
|
||||
return show_directory;
|
||||
}
|
||||
@@ -547,11 +566,52 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_dtype(struct dirent *de, const char *path)
|
||||
static int get_index_dtype(const char *path, int len)
|
||||
{
|
||||
int pos;
|
||||
struct cache_entry *ce;
|
||||
|
||||
ce = cache_name_exists(path, len, 0);
|
||||
if (ce) {
|
||||
if (!ce_uptodate(ce))
|
||||
return DT_UNKNOWN;
|
||||
if (S_ISGITLINK(ce->ce_mode))
|
||||
return DT_DIR;
|
||||
/*
|
||||
* Nobody actually cares about the
|
||||
* difference between DT_LNK and DT_REG
|
||||
*/
|
||||
return DT_REG;
|
||||
}
|
||||
|
||||
/* Try to look it up as a directory */
|
||||
pos = cache_name_pos(path, len);
|
||||
if (pos >= 0)
|
||||
return DT_UNKNOWN;
|
||||
pos = -pos-1;
|
||||
while (pos < active_nr) {
|
||||
ce = active_cache[pos++];
|
||||
if (strncmp(ce->name, path, len))
|
||||
break;
|
||||
if (ce->name[len] > '/')
|
||||
break;
|
||||
if (ce->name[len] < '/')
|
||||
continue;
|
||||
if (!ce_uptodate(ce))
|
||||
break; /* continue? */
|
||||
return DT_DIR;
|
||||
}
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
static int get_dtype(struct dirent *de, const char *path, int len)
|
||||
{
|
||||
int dtype = de ? DTYPE(de) : DT_UNKNOWN;
|
||||
struct stat st;
|
||||
|
||||
if (dtype != DT_UNKNOWN)
|
||||
return dtype;
|
||||
dtype = get_index_dtype(path, len);
|
||||
if (dtype != DT_UNKNOWN)
|
||||
return dtype;
|
||||
if (lstat(path, &st))
|
||||
@@ -574,15 +634,15 @@ static int get_dtype(struct dirent *de, const char *path)
|
||||
* Also, we ignore the name ".git" (even if it is not a directory).
|
||||
* That likely will not change.
|
||||
*/
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
{
|
||||
DIR *fdir = opendir(*path ? path : ".");
|
||||
DIR *fdir = opendir(*base ? base : ".");
|
||||
int contents = 0;
|
||||
|
||||
if (fdir) {
|
||||
struct dirent *de;
|
||||
char fullname[PATH_MAX + 1];
|
||||
memcpy(fullname, base, baselen);
|
||||
char path[PATH_MAX + 1];
|
||||
memcpy(path, base, baselen);
|
||||
|
||||
while ((de = readdir(fdir)) != NULL) {
|
||||
int len, dtype;
|
||||
@@ -593,17 +653,18 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
len = strlen(de->d_name);
|
||||
/* Ignore overly long pathnames! */
|
||||
if (len + baselen + 8 > sizeof(fullname))
|
||||
if (len + baselen + 8 > sizeof(path))
|
||||
continue;
|
||||
memcpy(fullname + baselen, de->d_name, len+1);
|
||||
if (simplify_away(fullname, baselen + len, simplify))
|
||||
memcpy(path + baselen, de->d_name, len+1);
|
||||
len = baselen + len;
|
||||
if (simplify_away(path, len, simplify))
|
||||
continue;
|
||||
|
||||
dtype = DTYPE(de);
|
||||
exclude = excluded(dir, fullname, &dtype);
|
||||
exclude = excluded(dir, path, &dtype);
|
||||
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
|
||||
&& in_pathspec(fullname, baselen + len, simplify))
|
||||
dir_add_ignored(dir, fullname, baselen + len);
|
||||
&& in_pathspec(path, len, simplify))
|
||||
dir_add_ignored(dir, path,len);
|
||||
|
||||
/*
|
||||
* Excluded? If we don't explicitly want to show
|
||||
@@ -613,7 +674,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
|
||||
if (dtype == DT_UNKNOWN)
|
||||
dtype = get_dtype(de, fullname);
|
||||
dtype = get_dtype(de, path, len);
|
||||
|
||||
/*
|
||||
* Do we want to see just the ignored files?
|
||||
@@ -630,9 +691,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
default:
|
||||
continue;
|
||||
case DT_DIR:
|
||||
memcpy(fullname + baselen + len, "/", 2);
|
||||
memcpy(path + len, "/", 2);
|
||||
len++;
|
||||
switch (treat_directory(dir, fullname, baselen + len, simplify)) {
|
||||
switch (treat_directory(dir, path, len, simplify)) {
|
||||
case show_directory:
|
||||
if (exclude != !!(dir->flags
|
||||
& DIR_SHOW_IGNORED))
|
||||
@@ -640,7 +701,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
break;
|
||||
case recurse_into_directory:
|
||||
contents += read_directory_recursive(dir,
|
||||
fullname, fullname, baselen + len, 0, simplify);
|
||||
path, len, 0, simplify);
|
||||
continue;
|
||||
case ignore_directory:
|
||||
continue;
|
||||
@@ -654,7 +715,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
if (check_only)
|
||||
goto exit_early;
|
||||
else
|
||||
dir_add_name(dir, fullname, baselen + len);
|
||||
dir_add_name(dir, path, len);
|
||||
}
|
||||
exit_early:
|
||||
closedir(fdir);
|
||||
@@ -717,15 +778,15 @@ static void free_simplify(struct path_simplify *simplify)
|
||||
free(simplify);
|
||||
}
|
||||
|
||||
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
|
||||
int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)
|
||||
{
|
||||
struct path_simplify *simplify;
|
||||
|
||||
if (has_symlink_leading_path(path, strlen(path)))
|
||||
if (has_symlink_leading_path(path, len))
|
||||
return dir->nr;
|
||||
|
||||
simplify = create_simplify(pathspec);
|
||||
read_directory_recursive(dir, path, base, baselen, 0, simplify);
|
||||
read_directory_recursive(dir, path, len, 0, simplify);
|
||||
free_simplify(simplify);
|
||||
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
|
||||
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
|
||||
@@ -759,7 +820,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);
|
||||
|
||||
5
dir.h
5
dir.h
@@ -61,14 +61,13 @@ struct dir_struct {
|
||||
char basebuf[PATH_MAX];
|
||||
};
|
||||
|
||||
extern int common_prefix(const char **pathspec);
|
||||
|
||||
#define MATCHED_RECURSIVELY 1
|
||||
#define MATCHED_FNMATCH 2
|
||||
#define MATCHED_EXACTLY 3
|
||||
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
|
||||
|
||||
extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
|
||||
extern int fill_directory(struct dir_struct *dir, const char **pathspec);
|
||||
extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);
|
||||
|
||||
extern int excluded(struct dir_struct *, const char *, int *);
|
||||
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
||||
|
||||
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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user