Merge branch 'maint' into jc/verify-pack-stat
* maint: (95 commits) verify-pack -v: do not report "chain length 0" t5510: harden the way verify-pack is used gitweb/README: Document $base_url Documentation: git submodule: add missing options to synopsis Better usage string for reflog. hg-to-git: don't import the unused popen2 module send-email: remove debug trace config: Keep inner whitespace verbatim GIT 1.6.4 GIT 1.6.3.4 config.txt: document add.ignore-errors request-pull: allow ls-remote to notice remote.$nickname.uploadpack Update the documentation of the raw diff output format git-rerere.txt: Clarify ambiguity of the config variable t9143: do not fail if Compress::Zlib is missing Trivial path quoting fixes in git-instaweb GIT 1.6.4-rc3 Documentation/config.txt: a variable can be defined on the section header line git svn: make minimize URL more reliable over http(s) Disable asciidoc 8.4.1+ semantics for `{plus}` and friends ...
This commit is contained in:
commit
7ecc9b153c
@ -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
|
||||
|
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.
|
||||
|
@ -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
|
||||
@ -1387,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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
------
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
|
@ -14,8 +14,8 @@ SYNOPSIS
|
||||
'git submodule' [--quiet] status [--cached] [--] [<path>...]
|
||||
'git submodule' [--quiet] init [--] [<path>...]
|
||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
|
||||
[--reference <repository>] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
[--reference <repository>] [--merge] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--cached] [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] foreach <command>
|
||||
'git submodule' [--quiet] sync [--] [<path>...]
|
||||
|
||||
|
@ -80,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
|
||||
@ -338,6 +349,10 @@ 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
|
||||
|
@ -43,9 +43,15 @@ 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.3/git.html[documentation for release 1.6.3.3]
|
||||
* 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],
|
||||
|
@ -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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.3.GIT
|
||||
DEF_VER=v1.6.4
|
||||
|
||||
LF='
|
||||
'
|
||||
|
36
Makefile
36
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.
|
||||
@ -726,6 +728,7 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
NO_EXTERNAL_GREP = YesPlease
|
||||
ifeq ($(uname_R),5.7)
|
||||
NEEDS_RESOLV = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
@ -828,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
|
||||
@ -1019,6 +1035,9 @@ ifdef NEEDS_LIBICONV
|
||||
endif
|
||||
EXTLIBS += $(ICONV_LINK) -liconv
|
||||
endif
|
||||
ifdef NEEDS_LIBGEN
|
||||
EXTLIBS += -lgen
|
||||
endif
|
||||
ifdef NEEDS_SOCKET
|
||||
EXTLIBS += -lsocket
|
||||
endif
|
||||
@ -1641,10 +1660,11 @@ ifneq (,$X)
|
||||
endif
|
||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||
{ $(RM) "$$execdir/git$X" && \
|
||||
{ test "$$bindir/" = "$$execdir/" || \
|
||||
{ $(RM) "$$execdir/git$X" && \
|
||||
test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
|
||||
ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \
|
||||
cp "$$bindir/git$X" "$$execdir/git$X"; } && \
|
||||
cp "$$bindir/git$X" "$$execdir/git$X"; } ; } && \
|
||||
{ for p in $(BUILT_INS); do \
|
||||
$(RM) "$$execdir/$$p" && \
|
||||
ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -2255,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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -694,7 +694,7 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
||||
*/
|
||||
|
||||
static const char reflog_usage[] =
|
||||
"git reflog (expire | ...)";
|
||||
"git reflog [ show | expire | delete ]";
|
||||
|
||||
int cmd_reflog(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
|
@ -8,10 +8,13 @@
|
||||
|
||||
static void show_pack_info(struct packed_git *p)
|
||||
{
|
||||
uint32_t nr_objects, i, chain_histogram[MAX_CHAIN+1];
|
||||
uint32_t nr_objects, i;
|
||||
int cnt;
|
||||
unsigned long chain_histogram[MAX_CHAIN+1], baseobjects;
|
||||
|
||||
nr_objects = p->num_objects;
|
||||
memset(chain_histogram, 0, sizeof(chain_histogram));
|
||||
baseobjects = 0;
|
||||
|
||||
for (i = 0; i < nr_objects; i++) {
|
||||
const unsigned char *sha1;
|
||||
@ -30,9 +33,11 @@ static void show_pack_info(struct packed_git *p)
|
||||
&delta_chain_length,
|
||||
base_sha1);
|
||||
printf("%s ", sha1_to_hex(sha1));
|
||||
if (!delta_chain_length)
|
||||
if (!delta_chain_length) {
|
||||
printf("%-6s %lu %lu %"PRIuMAX"\n",
|
||||
type, size, store_size, (uintmax_t)offset);
|
||||
baseobjects++;
|
||||
}
|
||||
else {
|
||||
printf("%-6s %lu %lu %"PRIuMAX" %u %s\n",
|
||||
type, size, store_size, (uintmax_t)offset,
|
||||
@ -44,15 +49,21 @@ static void show_pack_info(struct packed_git *p)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= MAX_CHAIN; i++) {
|
||||
if (!chain_histogram[i])
|
||||
if (baseobjects)
|
||||
printf("non delta: %lu object%s\n",
|
||||
baseobjects, baseobjects > 1 ? "s" : "");
|
||||
|
||||
for (cnt = 1; cnt <= MAX_CHAIN; cnt++) {
|
||||
if (!chain_histogram[cnt])
|
||||
continue;
|
||||
printf("chain length = %"PRIu32": %"PRIu32" object%s\n", i,
|
||||
chain_histogram[i], chain_histogram[i] > 1 ? "s" : "");
|
||||
printf("chain length = %d: %lu object%s\n", cnt,
|
||||
chain_histogram[cnt],
|
||||
chain_histogram[cnt] > 1 ? "s" : "");
|
||||
}
|
||||
if (chain_histogram[0])
|
||||
printf("chain length > %d: %"PRIu32" object%s\n", MAX_CHAIN,
|
||||
chain_histogram[0], chain_histogram[0] > 1 ? "s" : "");
|
||||
printf("chain length > %d: %lu object%s\n", MAX_CHAIN,
|
||||
chain_histogram[0],
|
||||
chain_histogram[0] > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
static int verify_one_pack(const char *path, int verbose)
|
||||
|
@ -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 */
|
||||
|
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)
|
||||
|
6
commit.c
6
commit.c
@ -262,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)
|
||||
|
51
config.c
51
config.c
@ -62,7 +62,8 @@ static char *parse_value(void)
|
||||
if (comment)
|
||||
continue;
|
||||
if (isspace(c) && !quote) {
|
||||
space = 1;
|
||||
if (len)
|
||||
space++;
|
||||
continue;
|
||||
}
|
||||
if (!quote) {
|
||||
@ -71,11 +72,8 @@ static char *parse_value(void)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (space) {
|
||||
if (len)
|
||||
value[len++] = ' ';
|
||||
space = 0;
|
||||
}
|
||||
for (; space; space--)
|
||||
value[len++] = ' ';
|
||||
if (c == '\\') {
|
||||
c = get_next_char();
|
||||
switch (c) {
|
||||
@ -1174,7 +1172,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 +1195,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 +1235,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 +1252,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@
|
||||
|
13
configure.ac
13
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)
|
||||
|
||||
@ -479,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])
|
||||
#
|
||||
|
@ -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=
|
||||
|
@ -20,7 +20,7 @@
|
||||
"""
|
||||
|
||||
import os, os.path, sys
|
||||
import tempfile, popen2, pickle, getopt
|
||||
import tempfile, pickle, getopt
|
||||
import re
|
||||
|
||||
# Maps hg version -> git version
|
||||
|
111
dir.c
111
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);
|
||||
|
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);
|
||||
|
@ -42,11 +42,12 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
|
||||
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
|
||||
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
|
||||
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
|
||||
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
|
||||
enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
|
||||
#ifndef OBJECT_CREATION_MODE
|
||||
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
|
||||
#endif
|
||||
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
|
||||
int grafts_replace_parents = 1;
|
||||
|
||||
/* Parallel index stat data preload? */
|
||||
int core_preload_index = 0;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define TYPEOF(x) (__typeof__(x))
|
||||
@ -33,9 +34,11 @@
|
||||
#define TYPEOF(x)
|
||||
#endif
|
||||
|
||||
#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
|
||||
#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (bitsizeof(x) - (bits))))
|
||||
#define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
/* Approximation of the length of the decimal representation of this type. */
|
||||
#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
|
||||
|
||||
@ -52,7 +55,7 @@
|
||||
# else
|
||||
# define _XOPEN_SOURCE 500
|
||||
# endif
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX)
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX) && !defined(sgi)
|
||||
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
|
||||
#ifndef __sun__
|
||||
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
|
||||
@ -62,6 +65,7 @@
|
||||
#define _GNU_SOURCE 1
|
||||
#define _BSD_SOURCE 1
|
||||
#define _NETBSD_SOURCE 1
|
||||
#define _SGI_SOURCE 1
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
@ -256,7 +256,7 @@ apache2_conf () {
|
||||
mkdir -p "$GIT_DIR/gitweb/logs"
|
||||
bind=
|
||||
test x"$local" = xtrue && bind='127.0.0.1:'
|
||||
echo 'text/css css' > $fqgitdir/mime.types
|
||||
echo 'text/css css' > "$fqgitdir/mime.types"
|
||||
cat > "$conf" <<EOF
|
||||
ServerName "git-instaweb"
|
||||
ServerRoot "$fqgitdir/gitweb"
|
||||
@ -272,7 +272,7 @@ EOF
|
||||
fi
|
||||
done
|
||||
cat >> "$conf" <<EOF
|
||||
TypesConfig $fqgitdir/mime.types
|
||||
TypesConfig "$fqgitdir/mime.types"
|
||||
DirectoryIndex gitweb.cgi
|
||||
EOF
|
||||
|
||||
|
@ -703,7 +703,7 @@ first and then run 'git rebase --continue' again."
|
||||
preserve=t
|
||||
for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
|
||||
do
|
||||
if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
|
||||
if test -f "$REWRITTEN"/$p -a \( $p != $ONTO -o $sha1 = $first_after_upstream \)
|
||||
then
|
||||
preserve=f
|
||||
fi
|
||||
|
@ -81,7 +81,7 @@ case ",$all_into_one," in
|
||||
esac
|
||||
|
||||
args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra"
|
||||
names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
|
||||
names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
|
||||
exit 1
|
||||
if [ -z "$names" ]; then
|
||||
say Nothing new to pack.
|
||||
|
@ -28,13 +28,13 @@ headrev=`git rev-parse --verify "$head"^0` || exit
|
||||
merge_base=`git merge-base $baserev $headrev` ||
|
||||
die "fatal: No commits in common between $base and $head"
|
||||
|
||||
url=$(get_remote_url "$url")
|
||||
branch=$(git ls-remote "$url" \
|
||||
| sed -n -e "/^$headrev refs.heads./{
|
||||
s/^.* refs.heads.//
|
||||
p
|
||||
q
|
||||
}")
|
||||
url=$(get_remote_url "$url")
|
||||
if [ -z "$branch" ]; then
|
||||
echo "warn: No branch of $url is at:" >&2
|
||||
git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2
|
||||
|
@ -450,7 +450,6 @@ sub check_file_rev_conflict($) {
|
||||
try {
|
||||
$repo->command('rev-parse', '--verify', '--quiet', $f);
|
||||
if (defined($format_patch)) {
|
||||
print "foo\n";
|
||||
return $format_patch;
|
||||
}
|
||||
die(<<EOF);
|
||||
@ -654,13 +653,17 @@ if (!@to) {
|
||||
}
|
||||
|
||||
sub expand_aliases {
|
||||
my @cur = @_;
|
||||
my @last;
|
||||
do {
|
||||
@last = @cur;
|
||||
@cur = map { $aliases{$_} ? @{$aliases{$_}} : $_ } @last;
|
||||
} while (join(',',@cur) ne join(',',@last));
|
||||
return @cur;
|
||||
return map { expand_one_alias($_) } @_;
|
||||
}
|
||||
|
||||
my %EXPANDED_ALIASES;
|
||||
sub expand_one_alias {
|
||||
my $alias = shift;
|
||||
if ($EXPANDED_ALIASES{$alias}) {
|
||||
die "fatal: alias '$alias' expands to itself\n";
|
||||
}
|
||||
local $EXPANDED_ALIASES{$alias} = 1;
|
||||
return $aliases{$alias} ? expand_aliases(@{$aliases{$alias}}) : $alias;
|
||||
}
|
||||
|
||||
@to = expand_aliases(@to);
|
||||
|
@ -203,7 +203,7 @@ apply_stash () {
|
||||
git diff-tree --binary $s^2^..$s^2 | git apply --cached
|
||||
test $? -ne 0 &&
|
||||
die 'Conflicts in index. Try without --index.'
|
||||
unstashed_index_tree=$(git-write-tree) ||
|
||||
unstashed_index_tree=$(git write-tree) ||
|
||||
die 'Could not save index tree'
|
||||
git reset
|
||||
fi
|
||||
@ -219,7 +219,7 @@ apply_stash () {
|
||||
then
|
||||
export GIT_MERGE_VERBOSITY=0
|
||||
fi
|
||||
if git-merge-recursive $b_tree -- $c_tree $w_tree
|
||||
if git merge-recursive $b_tree -- $c_tree $w_tree
|
||||
then
|
||||
# No conflict
|
||||
if test -n "$unstashed_index_tree"
|
||||
@ -297,7 +297,7 @@ apply_to_branch () {
|
||||
fi
|
||||
stash=$2
|
||||
|
||||
git-checkout -b $branch $stash^ &&
|
||||
git checkout -b $branch $stash^ &&
|
||||
apply_stash --index $stash &&
|
||||
drop_stash $stash
|
||||
}
|
||||
|
172
git-svn.perl
172
git-svn.perl
@ -19,6 +19,7 @@ $ENV{GIT_DIR} ||= '.git';
|
||||
$Git::SVN::default_repo_id = 'svn';
|
||||
$Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
|
||||
$Git::SVN::Ra::_log_window_size = 100;
|
||||
$Git::SVN::_minimize_url = 'unset';
|
||||
|
||||
$Git::SVN::Log::TZ = $ENV{TZ};
|
||||
$ENV{TZ} = 'UTC';
|
||||
@ -31,6 +32,7 @@ require SVN::Delta;
|
||||
if ($SVN::Core::VERSION lt '1.1.0') {
|
||||
fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
|
||||
}
|
||||
my $can_compress = eval { require Compress::Zlib; 1};
|
||||
push @Git::SVN::Ra::ISA, 'SVN::Ra';
|
||||
push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
|
||||
push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
|
||||
@ -40,6 +42,7 @@ use IO::File qw//;
|
||||
use File::Basename qw/dirname basename/;
|
||||
use File::Path qw/mkpath/;
|
||||
use File::Spec;
|
||||
use File::Find;
|
||||
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
|
||||
use IPC::Open3;
|
||||
use Git;
|
||||
@ -98,7 +101,7 @@ my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
|
||||
'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
|
||||
'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
|
||||
'stdlayout|s' => \$_stdlayout,
|
||||
'minimize-url|m' => \$Git::SVN::_minimize_url,
|
||||
'minimize-url|m!' => \$Git::SVN::_minimize_url,
|
||||
'no-metadata' => sub { $icv{noMetadata} = 1 },
|
||||
'use-svm-props' => sub { $icv{useSvmProps} = 1 },
|
||||
'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
|
||||
@ -217,6 +220,10 @@ my %cmd = (
|
||||
"Undo fetches back to the specified SVN revision",
|
||||
{ 'revision|r=s' => \$_revision,
|
||||
'parent|p' => \$_fetch_parent } ],
|
||||
'gc' => [ \&cmd_gc,
|
||||
"Compress unhandled.log files in .git/svn and remove " .
|
||||
"index files in .git/svn",
|
||||
{} ],
|
||||
);
|
||||
|
||||
my $cmd;
|
||||
@ -393,6 +400,10 @@ sub cmd_init {
|
||||
init_subdir(@_);
|
||||
do_git_init_db();
|
||||
|
||||
if ($Git::SVN::_minimize_url eq 'unset') {
|
||||
$Git::SVN::_minimize_url = 0;
|
||||
}
|
||||
|
||||
Git::SVN->init($url);
|
||||
}
|
||||
|
||||
@ -655,9 +666,22 @@ sub cmd_branch {
|
||||
}
|
||||
}
|
||||
unless (defined $glob) {
|
||||
die "Unknown ",
|
||||
$_tag ? "tag" : "branch",
|
||||
" destination $_branch_dest\n";
|
||||
my $dest_re = qr/\b\Q$_branch_dest\E\b/;
|
||||
foreach my $g (@{$allglobs}) {
|
||||
$g->{path}->{left} =~ /$dest_re/ or next;
|
||||
if (defined $glob) {
|
||||
die "Ambiguous destination: ",
|
||||
$_branch_dest, "\nmatches both '",
|
||||
$glob->{path}->{left}, "' and '",
|
||||
$g->{path}->{left}, "'\n";
|
||||
}
|
||||
$glob = $g;
|
||||
}
|
||||
unless (defined $glob) {
|
||||
die "Unknown ",
|
||||
$_tag ? "tag" : "branch",
|
||||
" destination $_branch_dest\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
|
||||
@ -876,10 +900,6 @@ sub cmd_multi_init {
|
||||
usage(1);
|
||||
}
|
||||
|
||||
# there are currently some bugs that prevent multi-init/multi-fetch
|
||||
# setups from working well without this.
|
||||
$Git::SVN::_minimize_url = 1;
|
||||
|
||||
$_prefix = '' unless defined $_prefix;
|
||||
if (defined $url) {
|
||||
$url = canonicalize_url($url);
|
||||
@ -1111,6 +1131,14 @@ sub cmd_reset {
|
||||
print "r$r = $c ($gs->{ref_id})\n";
|
||||
}
|
||||
|
||||
sub cmd_gc {
|
||||
if (!$can_compress) {
|
||||
warn "Compress::Zlib could not be found; unhandled.log " .
|
||||
"files will not be compressed.\n";
|
||||
}
|
||||
find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn");
|
||||
}
|
||||
|
||||
########################### utility functions #########################
|
||||
|
||||
sub rebase_cmd {
|
||||
@ -1180,7 +1208,7 @@ sub complete_url_ls_init {
|
||||
"wanted to set to: $gs->{url}\n";
|
||||
}
|
||||
command_oneline('config', $k, $gs->{url}) unless $orig_url;
|
||||
my $remote_path = "$ra->{svn_path}/$repo_path";
|
||||
my $remote_path = "$gs->{path}/$repo_path";
|
||||
$remote_path =~ s#/+#/#g;
|
||||
$remote_path =~ s#^/##g;
|
||||
$remote_path .= "/*" if $remote_path !~ /\*/;
|
||||
@ -1363,11 +1391,11 @@ sub read_repo_config {
|
||||
sub extract_metadata {
|
||||
my $id = shift or return (undef, undef, undef);
|
||||
my ($url, $rev, $uuid) = ($id =~ /^\s*git-svn-id:\s+(.*)\@(\d+)
|
||||
\s([a-f\d\-]+)$/x);
|
||||
\s([a-f\d\-]+)$/ix);
|
||||
if (!defined $rev || !$uuid || !$url) {
|
||||
# some of the original repositories I made had
|
||||
# identifiers like this:
|
||||
($rev, $uuid) = ($id =~/^\s*git-svn-id:\s(\d+)\@([a-f\d\-]+)/);
|
||||
($rev, $uuid) = ($id =~/^\s*git-svn-id:\s(\d+)\@([a-f\d\-]+)/i);
|
||||
}
|
||||
return ($url, $rev, $uuid);
|
||||
}
|
||||
@ -1531,6 +1559,25 @@ sub md5sum {
|
||||
return $md5->hexdigest();
|
||||
}
|
||||
|
||||
sub gc_directory {
|
||||
if ($can_compress && -f $_ && basename($_) eq "unhandled.log") {
|
||||
my $out_filename = $_ . ".gz";
|
||||
open my $in_fh, "<", $_ or die "Unable to open $_: $!\n";
|
||||
binmode $in_fh;
|
||||
my $gz = Compress::Zlib::gzopen($out_filename, "ab") or
|
||||
die "Unable to open $out_filename: $!\n";
|
||||
|
||||
my $res;
|
||||
while ($res = sysread($in_fh, my $str, 1024)) {
|
||||
$gz->gzwrite($str) or
|
||||
die "Unable to write: ".$gz->gzerror()."!\n";
|
||||
}
|
||||
unlink $_ or die "unlink $File::Find::name: $!\n";
|
||||
} elsif (-f $_ && basename($_) eq "index") {
|
||||
unlink $_ or die "unlink $_: $!\n";
|
||||
}
|
||||
}
|
||||
|
||||
package Git::SVN;
|
||||
use strict;
|
||||
use warnings;
|
||||
@ -1651,6 +1698,7 @@ sub fetch_all {
|
||||
my $ra = Git::SVN::Ra->new($url);
|
||||
my $uuid = $ra->get_uuid;
|
||||
my $head = $ra->get_latest_revnum;
|
||||
$ra->get_log("", $head, 0, 1, 0, 1, sub { $head = $_[1] });
|
||||
my $base = defined $fetch ? $head : 0;
|
||||
|
||||
# read the max revs for wildcard expansion (branches/*, tags/*)
|
||||
@ -2014,7 +2062,7 @@ sub _set_svm_vars {
|
||||
|
||||
chomp($src, $uuid);
|
||||
|
||||
$uuid =~ m{^[0-9a-f\-]{30,}$}
|
||||
$uuid =~ m{^[0-9a-f\-]{30,}$}i
|
||||
or die "doesn't look right - svm:uuid is '$uuid'\n";
|
||||
|
||||
# the '!' is used to mark the repos_root!/relative/path
|
||||
@ -2100,7 +2148,7 @@ sub svnsync {
|
||||
die "doesn't look right - svn:sync-from-url is '$url'\n";
|
||||
|
||||
my $uuid = tmp_config('--get', "$section.svnsync-uuid");
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
|
||||
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
|
||||
|
||||
$svnsync = { url => $url, uuid => $uuid }
|
||||
@ -2118,7 +2166,7 @@ sub svnsync {
|
||||
die "doesn't look right - svn:sync-from-url is '$url'\n";
|
||||
|
||||
my $uuid = $rp->{'svn:sync-from-uuid'} or die $err . "uuid\n";
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
|
||||
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
|
||||
|
||||
my $section = "svn-remote.$self->{repo_id}";
|
||||
@ -2134,7 +2182,7 @@ sub ra_uuid {
|
||||
unless ($self->{ra_uuid}) {
|
||||
my $key = "svn-remote.$self->{repo_id}.uuid";
|
||||
my $uuid = eval { tmp_config('--get', $key) };
|
||||
if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/) {
|
||||
if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/i) {
|
||||
$self->{ra_uuid} = $uuid;
|
||||
} else {
|
||||
die "ra_uuid called without URL\n" unless $self->{url};
|
||||
@ -2177,16 +2225,6 @@ sub ra {
|
||||
$ra;
|
||||
}
|
||||
|
||||
sub rel_path {
|
||||
my ($self) = @_;
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
return $self->{path} if ($self->{url} eq $repos_root);
|
||||
my $url = $self->{url} .
|
||||
(length $self->{path} ? "/$self->{path}" : $self->{path});
|
||||
$url =~ s!^\Q$repos_root\E(?:/+|$)!!g;
|
||||
$url;
|
||||
}
|
||||
|
||||
# prop_walk(PATH, REV, SUB)
|
||||
# -------------------------
|
||||
# Recursively traverse PATH at revision REV and invoke SUB for each
|
||||
@ -2512,10 +2550,7 @@ sub match_paths {
|
||||
if (my $path = $paths->{"/$self->{path}"}) {
|
||||
return ($path->{action} eq 'D') ? 0 : 1;
|
||||
}
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
my $extended_path = $self->{url} . '/' . $self->{path};
|
||||
$extended_path =~ s#^\Q$repos_root\E(/|$)##;
|
||||
$self->{path_regex} ||= qr/^\/\Q$extended_path\E\//;
|
||||
$self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
|
||||
if (grep /$self->{path_regex}/, keys %$paths) {
|
||||
return 1;
|
||||
}
|
||||
@ -2538,15 +2573,14 @@ sub find_parent_branch {
|
||||
unless (defined $paths) {
|
||||
my $err_handler = $SVN::Error::handler;
|
||||
$SVN::Error::handler = \&Git::SVN::Ra::skip_unknown_revs;
|
||||
$self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1, sub {
|
||||
$paths =
|
||||
Git::SVN::Ra::dup_changed_paths($_[0]) });
|
||||
$self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1,
|
||||
sub { $paths = $_[0] });
|
||||
$SVN::Error::handler = $err_handler;
|
||||
}
|
||||
return undef unless defined $paths;
|
||||
|
||||
# look for a parent from another branch:
|
||||
my @b_path_components = split m#/#, $self->rel_path;
|
||||
my @b_path_components = split m#/#, $self->{path};
|
||||
my @a_path_components;
|
||||
my $i;
|
||||
while (@b_path_components) {
|
||||
@ -2564,11 +2598,11 @@ sub find_parent_branch {
|
||||
my $r = $i->{copyfrom_rev};
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
my $url = $self->ra->{url};
|
||||
my $new_url = $repos_root . $branch_from;
|
||||
my $new_url = $url . $branch_from;
|
||||
print STDERR "Found possible branch point: ",
|
||||
"$new_url => ", $self->full_url, ", $r\n";
|
||||
$branch_from =~ s#^/##;
|
||||
my $gs = $self->other_gs($new_url, $url, $repos_root,
|
||||
my $gs = $self->other_gs($new_url, $url,
|
||||
$branch_from, $r, $self->{ref_id});
|
||||
my ($r0, $parent) = $gs->find_rev_before($r, 1);
|
||||
{
|
||||
@ -2753,9 +2787,9 @@ sub parse_svn_date {
|
||||
}
|
||||
|
||||
sub other_gs {
|
||||
my ($self, $new_url, $url, $repos_root,
|
||||
my ($self, $new_url, $url,
|
||||
$branch_from, $r, $old_ref_id) = @_;
|
||||
my $gs = Git::SVN->find_by_url($new_url, $repos_root, $branch_from);
|
||||
my $gs = Git::SVN->find_by_url($new_url, $url, $branch_from);
|
||||
unless ($gs) {
|
||||
my $ref_id = $old_ref_id;
|
||||
$ref_id =~ s/\@\d+$//;
|
||||
@ -2866,7 +2900,7 @@ sub make_log_entry {
|
||||
die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
|
||||
"options set!\n";
|
||||
}
|
||||
my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$};
|
||||
my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i;
|
||||
# we don't want "SVM: initializing mirror for junk" ...
|
||||
return undef if $r == 0;
|
||||
my $svm = $self->svm;
|
||||
@ -3971,7 +4005,7 @@ sub repo_path {
|
||||
sub url_path {
|
||||
my ($self, $path) = @_;
|
||||
if ($self->{url} =~ m#^https?://#) {
|
||||
$path =~ s/([^~a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
|
||||
$path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg;
|
||||
}
|
||||
$self->{url} . '/' . $self->repo_path($path);
|
||||
}
|
||||
@ -4431,6 +4465,34 @@ sub get_log {
|
||||
my ($self, @args) = @_;
|
||||
my $pool = SVN::Pool->new;
|
||||
|
||||
# svn_log_changed_path_t objects passed to get_log are likely to be
|
||||
# overwritten even if only the refs are copied to an external variable,
|
||||
# so we should dup the structures in their entirety. Using an
|
||||
# externally passed pool (instead of our temporary and quickly cleared
|
||||
# pool in Git::SVN::Ra) does not help matters at all...
|
||||
my $receiver = pop @args;
|
||||
my $prefix = "/".$self->{svn_path};
|
||||
$prefix =~ s#/+($)##;
|
||||
my $prefix_regex = qr#^\Q$prefix\E#;
|
||||
push(@args, sub {
|
||||
my ($paths) = $_[0];
|
||||
return &$receiver(@_) unless $paths;
|
||||
$_[0] = ();
|
||||
foreach my $p (keys %$paths) {
|
||||
my $i = $paths->{$p};
|
||||
# Make path relative to our url, not repos_root
|
||||
$p =~ s/$prefix_regex//;
|
||||
my %s = map { $_ => $i->$_; }
|
||||
qw/copyfrom_path copyfrom_rev action/;
|
||||
if ($s{'copyfrom_path'}) {
|
||||
$s{'copyfrom_path'} =~ s/$prefix_regex//;
|
||||
}
|
||||
$_[0]{$p} = \%s;
|
||||
}
|
||||
&$receiver(@_);
|
||||
});
|
||||
|
||||
|
||||
# the limit parameter was not supported in SVN 1.1.x, so we
|
||||
# drop it. Therefore, the receiver callback passed to it
|
||||
# is made aware of this limitation by being wrapped if
|
||||
@ -4515,10 +4577,12 @@ sub gs_do_switch {
|
||||
|
||||
my $full_url = $self->{url};
|
||||
my $old_url = $full_url;
|
||||
$full_url .= '/' . escape_uri_only($path) if length $path;
|
||||
$full_url .= '/' . $path if length $path;
|
||||
my ($ra, $reparented);
|
||||
|
||||
if ($old_url =~ m#^svn(\+ssh)?://#) {
|
||||
if ($old_url =~ m#^svn(\+ssh)?://# ||
|
||||
($full_url =~ m#^https?://# &&
|
||||
escape_url($full_url) ne $full_url)) {
|
||||
$_[0] = undef;
|
||||
$self = undef;
|
||||
$RA = undef;
|
||||
@ -4600,7 +4664,7 @@ sub gs_fetch_loop_common {
|
||||
};
|
||||
sub _cb {
|
||||
my ($paths, $r, $author, $date, $log) = @_;
|
||||
[ dup_changed_paths($paths),
|
||||
[ $paths,
|
||||
{ author => $author, date => $date, log => $log } ];
|
||||
}
|
||||
$self->get_log([$longest_path], $min, $max, 0, 1, 1,
|
||||
@ -4767,7 +4831,11 @@ sub minimize_url {
|
||||
my $c = '';
|
||||
do {
|
||||
$url .= "/$c" if length $c;
|
||||
eval { (ref $self)->new($url)->get_latest_revnum };
|
||||
eval {
|
||||
my $ra = (ref $self)->new($url);
|
||||
my $latest = $ra->get_latest_revnum;
|
||||
$ra->get_log("", $latest, 0, 1, 0, 1, sub {});
|
||||
};
|
||||
} while ($@ && ($c = shift @components));
|
||||
$url;
|
||||
}
|
||||
@ -4823,24 +4891,6 @@ sub skip_unknown_revs {
|
||||
die "Error from SVN, ($errno): ", $err->expanded_message,"\n";
|
||||
}
|
||||
|
||||
# svn_log_changed_path_t objects passed to get_log are likely to be
|
||||
# overwritten even if only the refs are copied to an external variable,
|
||||
# so we should dup the structures in their entirety. Using an externally
|
||||
# passed pool (instead of our temporary and quickly cleared pool in
|
||||
# Git::SVN::Ra) does not help matters at all...
|
||||
sub dup_changed_paths {
|
||||
my ($paths) = @_;
|
||||
return undef unless $paths;
|
||||
my %ret;
|
||||
foreach my $p (keys %$paths) {
|
||||
my $i = $paths->{$p};
|
||||
my %s = map { $_ => $i->$_ }
|
||||
qw/copyfrom_path copyfrom_rev action/;
|
||||
$ret{$p} = \%s;
|
||||
}
|
||||
\%ret;
|
||||
}
|
||||
|
||||
package Git::SVN::Log;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -165,6 +165,12 @@ not include variables usually directly set during build):
|
||||
Full URL and absolute URL of gitweb script;
|
||||
in earlier versions of gitweb you might have need to set those
|
||||
variables, now there should be no need to do it.
|
||||
* $base_url
|
||||
Base URL for relative URLs in pages generated by gitweb,
|
||||
(e.g. $logo, $favicon, @stylesheets if they are relative URLs),
|
||||
needed and used only for URLs with nonempty PATH_INFO via
|
||||
<base href="$base_url>. Usually gitweb sets its value correctly,
|
||||
and there is no need to set this variable, e.g. to $my_uri or "/".
|
||||
* $home_link
|
||||
Target of the home link on top of all pages (the first part of view
|
||||
"breadcrumbs"). By default set to absolute URI of a page ($my_uri).
|
||||
|
@ -94,7 +94,7 @@ our $favicon = "++GITWEB_FAVICON++";
|
||||
# URI and label (title) of GIT logo link
|
||||
#our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/";
|
||||
#our $logo_label = "git documentation";
|
||||
our $logo_url = "http://git.or.cz/";
|
||||
our $logo_url = "http://git-scm.com/";
|
||||
our $logo_label = "git homepage";
|
||||
|
||||
# source of projects list
|
||||
|
2
graph.c
2
graph.c
@ -893,7 +893,7 @@ static struct column *find_new_column_by_commit(struct git_graph *graph,
|
||||
if (graph->new_columns[i].commit == commit)
|
||||
return &graph->new_columns[i];
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
|
||||
|
2
help.c
2
help.c
@ -100,7 +100,7 @@ static void pretty_print_string_list(struct cmdnames *cmds, int longest)
|
||||
|
||||
if (space < max_cols)
|
||||
cols = max_cols / space;
|
||||
rows = (cmds->cnt + cols - 1) / cols;
|
||||
rows = DIV_ROUND_UP(cmds->cnt, cols);
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
printf(" ");
|
||||
|
@ -149,8 +149,7 @@ void discard_revindex(void)
|
||||
if (pack_revindex_hashsz) {
|
||||
int i;
|
||||
for (i = 0; i < pack_revindex_hashsz; i++)
|
||||
if (pack_revindex[i].revindex)
|
||||
free(pack_revindex[i].revindex);
|
||||
free(pack_revindex[i].revindex);
|
||||
free(pack_revindex);
|
||||
pack_revindex_hashsz = 0;
|
||||
}
|
||||
|
@ -34,7 +34,9 @@ static void *preload_thread(void *_data)
|
||||
struct thread_data *p = _data;
|
||||
struct index_state *index = p->index;
|
||||
struct cache_entry **cep = index->cache + p->offset;
|
||||
struct cache_def cache;
|
||||
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
nr = p->nr;
|
||||
if (nr + p->offset > index->cache_nr)
|
||||
nr = index->cache_nr - p->offset;
|
||||
@ -49,6 +51,8 @@ static void *preload_thread(void *_data)
|
||||
continue;
|
||||
if (!ce_path_match(ce, p->pathspec))
|
||||
continue;
|
||||
if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
|
||||
continue;
|
||||
if (lstat(ce->name, &st))
|
||||
continue;
|
||||
if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY))
|
||||
@ -72,7 +76,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
|
||||
if (threads > MAX_PARALLEL)
|
||||
threads = MAX_PARALLEL;
|
||||
offset = 0;
|
||||
work = (index->cache_nr + threads - 1) / threads;
|
||||
work = DIV_ROUND_UP(index->cache_nr, threads);
|
||||
for (i = 0; i < threads; i++) {
|
||||
struct thread_data *p = data+i;
|
||||
p->index = index;
|
||||
|
9
refs.c
9
refs.c
@ -531,9 +531,10 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
|
||||
{
|
||||
if (strncmp(base, entry->name, trim))
|
||||
return 0;
|
||||
/* Is this a "negative ref" that represents a deleted ref? */
|
||||
if (is_null_sha1(entry->sha1))
|
||||
return 0;
|
||||
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
|
||||
if (is_null_sha1(entry->sha1))
|
||||
return 0;
|
||||
if (!has_sha1_file(entry->sha1)) {
|
||||
error("%s does not point to a valid object!", entry->name);
|
||||
return 0;
|
||||
@ -1525,8 +1526,10 @@ int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long ofs,
|
||||
if (fstat(fileno(logfp), &statbuf) ||
|
||||
statbuf.st_size < ofs ||
|
||||
fseek(logfp, -ofs, SEEK_END) ||
|
||||
fgets(buf, sizeof(buf), logfp))
|
||||
fgets(buf, sizeof(buf), logfp)) {
|
||||
fclose(logfp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), logfp)) {
|
||||
|
@ -133,7 +133,7 @@ void mark_parents_uninteresting(struct commit *commit)
|
||||
static void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
|
||||
{
|
||||
if (revs->no_walk && (obj->flags & UNINTERESTING))
|
||||
die("object ranges do not make sense when not walking revisions");
|
||||
revs->no_walk = 0;
|
||||
if (revs->reflog_info && obj->type == OBJ_COMMIT &&
|
||||
add_reflog_for_walk(revs->reflog_info,
|
||||
(struct commit *)obj, name))
|
||||
|
@ -1170,7 +1170,7 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
||||
size = c & 15;
|
||||
shift = 4;
|
||||
while (c & 0x80) {
|
||||
if (len <= used || sizeof(long) * 8 <= shift) {
|
||||
if (len <= used || bitsizeof(long) <= shift) {
|
||||
error("bad object header");
|
||||
return 0;
|
||||
}
|
||||
|
@ -777,8 +777,6 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
|
||||
for_each_recent_reflog_ent("HEAD", grab_nth_branch_switch, 40960, &cb);
|
||||
if (cb.cnt < nth) {
|
||||
cb.cnt = 0;
|
||||
for (i = 0; i < nth; i++)
|
||||
strbuf_release(&cb.buf[i]);
|
||||
for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
|
||||
}
|
||||
if (cb.cnt < nth)
|
||||
|
90
symlinks.c
90
symlinks.c
@ -32,19 +32,13 @@ static int longest_path_match(const char *name_a, int len_a,
|
||||
return match_len;
|
||||
}
|
||||
|
||||
static struct cache_def {
|
||||
char path[PATH_MAX + 1];
|
||||
int len;
|
||||
int flags;
|
||||
int track_flags;
|
||||
int prefix_len_stat_func;
|
||||
} cache;
|
||||
static struct cache_def default_cache;
|
||||
|
||||
static inline void reset_lstat_cache(void)
|
||||
static inline void reset_lstat_cache(struct cache_def *cache)
|
||||
{
|
||||
cache.path[0] = '\0';
|
||||
cache.len = 0;
|
||||
cache.flags = 0;
|
||||
cache->path[0] = '\0';
|
||||
cache->len = 0;
|
||||
cache->flags = 0;
|
||||
/*
|
||||
* The track_flags and prefix_len_stat_func members is only
|
||||
* set by the safeguard rule inside lstat_cache()
|
||||
@ -70,23 +64,23 @@ static inline void reset_lstat_cache(void)
|
||||
* of the prefix, where the cache should use the stat() function
|
||||
* instead of the lstat() function to test each path component.
|
||||
*/
|
||||
static int lstat_cache(const char *name, int len,
|
||||
static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
||||
int track_flags, int prefix_len_stat_func)
|
||||
{
|
||||
int match_len, last_slash, last_slash_dir, previous_slash;
|
||||
int match_flags, ret_flags, save_flags, max_len, ret;
|
||||
struct stat st;
|
||||
|
||||
if (cache.track_flags != track_flags ||
|
||||
cache.prefix_len_stat_func != prefix_len_stat_func) {
|
||||
if (cache->track_flags != track_flags ||
|
||||
cache->prefix_len_stat_func != prefix_len_stat_func) {
|
||||
/*
|
||||
* As a safeguard rule we clear the cache if the
|
||||
* values of track_flags and/or prefix_len_stat_func
|
||||
* does not match with the last supplied values.
|
||||
*/
|
||||
reset_lstat_cache();
|
||||
cache.track_flags = track_flags;
|
||||
cache.prefix_len_stat_func = prefix_len_stat_func;
|
||||
reset_lstat_cache(cache);
|
||||
cache->track_flags = track_flags;
|
||||
cache->prefix_len_stat_func = prefix_len_stat_func;
|
||||
match_len = last_slash = 0;
|
||||
} else {
|
||||
/*
|
||||
@ -94,10 +88,10 @@ static int lstat_cache(const char *name, int len,
|
||||
* the 2 "excluding" path types.
|
||||
*/
|
||||
match_len = last_slash =
|
||||
longest_path_match(name, len, cache.path, cache.len,
|
||||
longest_path_match(name, len, cache->path, cache->len,
|
||||
&previous_slash);
|
||||
match_flags = cache.flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (match_flags && match_len == cache.len)
|
||||
match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (match_flags && match_len == cache->len)
|
||||
return match_flags;
|
||||
/*
|
||||
* If we now have match_len > 0, we would know that
|
||||
@ -121,18 +115,18 @@ static int lstat_cache(const char *name, int len,
|
||||
max_len = len < PATH_MAX ? len : PATH_MAX;
|
||||
while (match_len < max_len) {
|
||||
do {
|
||||
cache.path[match_len] = name[match_len];
|
||||
cache->path[match_len] = name[match_len];
|
||||
match_len++;
|
||||
} while (match_len < max_len && name[match_len] != '/');
|
||||
if (match_len >= max_len && !(track_flags & FL_FULLPATH))
|
||||
break;
|
||||
last_slash = match_len;
|
||||
cache.path[last_slash] = '\0';
|
||||
cache->path[last_slash] = '\0';
|
||||
|
||||
if (last_slash <= prefix_len_stat_func)
|
||||
ret = stat(cache.path, &st);
|
||||
ret = stat(cache->path, &st);
|
||||
else
|
||||
ret = lstat(cache.path, &st);
|
||||
ret = lstat(cache->path, &st);
|
||||
|
||||
if (ret) {
|
||||
ret_flags = FL_LSTATERR;
|
||||
@ -156,9 +150,9 @@ static int lstat_cache(const char *name, int len,
|
||||
*/
|
||||
save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
|
||||
cache.path[last_slash] = '\0';
|
||||
cache.len = last_slash;
|
||||
cache.flags = save_flags;
|
||||
cache->path[last_slash] = '\0';
|
||||
cache->len = last_slash;
|
||||
cache->flags = save_flags;
|
||||
} else if ((track_flags & FL_DIR) &&
|
||||
last_slash_dir > 0 && last_slash_dir <= PATH_MAX) {
|
||||
/*
|
||||
@ -172,11 +166,11 @@ static int lstat_cache(const char *name, int len,
|
||||
* can still cache the path components before the last
|
||||
* one (the found symlink or non-existing component).
|
||||
*/
|
||||
cache.path[last_slash_dir] = '\0';
|
||||
cache.len = last_slash_dir;
|
||||
cache.flags = FL_DIR;
|
||||
cache->path[last_slash_dir] = '\0';
|
||||
cache->len = last_slash_dir;
|
||||
cache->flags = FL_DIR;
|
||||
} else {
|
||||
reset_lstat_cache();
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
return ret_flags;
|
||||
}
|
||||
@ -188,16 +182,17 @@ static int lstat_cache(const char *name, int len,
|
||||
void invalidate_lstat_cache(const char *name, int len)
|
||||
{
|
||||
int match_len, previous_slash;
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
|
||||
match_len = longest_path_match(name, len, cache.path, cache.len,
|
||||
match_len = longest_path_match(name, len, cache->path, cache->len,
|
||||
&previous_slash);
|
||||
if (len == match_len) {
|
||||
if ((cache.track_flags & FL_DIR) && previous_slash > 0) {
|
||||
cache.path[previous_slash] = '\0';
|
||||
cache.len = previous_slash;
|
||||
cache.flags = FL_DIR;
|
||||
if ((cache->track_flags & FL_DIR) && previous_slash > 0) {
|
||||
cache->path[previous_slash] = '\0';
|
||||
cache->len = previous_slash;
|
||||
cache->flags = FL_DIR;
|
||||
} else {
|
||||
reset_lstat_cache();
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -207,19 +202,26 @@ void invalidate_lstat_cache(const char *name, int len)
|
||||
*/
|
||||
void clear_lstat_cache(void)
|
||||
{
|
||||
reset_lstat_cache();
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
|
||||
#define USE_ONLY_LSTAT 0
|
||||
|
||||
/*
|
||||
* Return non-zero if path 'name' has a leading symlink component
|
||||
*/
|
||||
int threaded_has_symlink_leading_path(struct cache_def *cache, const char *name, int len)
|
||||
{
|
||||
return lstat_cache(cache, name, len, FL_SYMLINK|FL_DIR, USE_ONLY_LSTAT) & FL_SYMLINK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return non-zero if path 'name' has a leading symlink component
|
||||
*/
|
||||
int has_symlink_leading_path(const char *name, int len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
FL_SYMLINK|FL_DIR, USE_ONLY_LSTAT) &
|
||||
FL_SYMLINK;
|
||||
return threaded_has_symlink_leading_path(&default_cache, name, len);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -228,7 +230,8 @@ int has_symlink_leading_path(const char *name, int len)
|
||||
*/
|
||||
int has_symlink_or_noent_leading_path(const char *name, int len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
return lstat_cache(cache, name, len,
|
||||
FL_SYMLINK|FL_NOENT|FL_DIR, USE_ONLY_LSTAT) &
|
||||
(FL_SYMLINK|FL_NOENT);
|
||||
}
|
||||
@ -242,7 +245,8 @@ int has_symlink_or_noent_leading_path(const char *name, int len)
|
||||
*/
|
||||
int has_dirs_only_path(const char *name, int len, int prefix_len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
return lstat_cache(cache, name, len,
|
||||
FL_DIR|FL_FULLPATH, prefix_len) &
|
||||
FL_DIR;
|
||||
}
|
||||
|
@ -459,6 +459,28 @@ EOF
|
||||
|
||||
test_expect_success "rename succeeded" "test_cmp expect .git/config"
|
||||
|
||||
cat >> .git/config << EOF
|
||||
[branch "vier"] z = 1
|
||||
EOF
|
||||
|
||||
test_expect_success "rename a section with a var on the same line" \
|
||||
'git config --rename-section branch.vier branch.zwei'
|
||||
|
||||
cat > expect << EOF
|
||||
# Hallo
|
||||
#Bello
|
||||
[branch "zwei"]
|
||||
x = 1
|
||||
[branch "zwei"]
|
||||
y = 1
|
||||
[branch "drei"]
|
||||
weird
|
||||
[branch "zwei"]
|
||||
z = 1
|
||||
EOF
|
||||
|
||||
test_expect_success "rename succeeded" "test_cmp expect .git/config"
|
||||
|
||||
cat >> .git/config << EOF
|
||||
[branch "zwei"] a = 1 [branch "vier"]
|
||||
EOF
|
||||
@ -733,6 +755,11 @@ echo >>result
|
||||
|
||||
test_expect_success '--null --get-regexp' 'cmp result expect'
|
||||
|
||||
test_expect_success 'inner whitespace kept verbatim' '
|
||||
git config section.val "foo bar" &&
|
||||
test "z$(git config section.val)" = "zfoo bar"
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS 'symlinked configuration' '
|
||||
|
||||
ln -s notyet myconfig &&
|
||||
|
80
t/t3414-rebase-preserve-onto.sh
Executable file
80
t/t3414-rebase-preserve-onto.sh
Executable file
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Greg Price
|
||||
#
|
||||
|
||||
test_description='git rebase -p should respect --onto
|
||||
|
||||
In a rebase with --onto, we should rewrite all the commits that
|
||||
aren'"'"'t on top of $ONTO, even if they are on top of $UPSTREAM.
|
||||
'
|
||||
. ./test-lib.sh
|
||||
|
||||
. ../lib-rebase.sh
|
||||
|
||||
# Set up branches like this:
|
||||
# A1---B1---E1---F1---G1
|
||||
# \ \ /
|
||||
# \ \--C1---D1--/
|
||||
# H1
|
||||
|
||||
test_expect_success 'setup' '
|
||||
test_commit A1 &&
|
||||
test_commit B1 &&
|
||||
test_commit C1 &&
|
||||
test_commit D1 &&
|
||||
git reset --hard B1 &&
|
||||
test_commit E1 &&
|
||||
test_commit F1 &&
|
||||
test_merge G1 D1 &&
|
||||
git reset --hard A1 &&
|
||||
test_commit H1
|
||||
'
|
||||
|
||||
# Now rebase merge G1 from both branches' base B1, both should move:
|
||||
# A1---B1---E1---F1---G1
|
||||
# \ \ /
|
||||
# \ \--C1---D1--/
|
||||
# \
|
||||
# H1---E2---F2---G2
|
||||
# \ /
|
||||
# \--C2---D2--/
|
||||
|
||||
test_expect_success 'rebase from B1 onto H1' '
|
||||
git checkout G1 &&
|
||||
git rebase -p --onto H1 B1 &&
|
||||
test "$(git rev-parse HEAD^1^1^1)" = "$(git rev-parse H1)" &&
|
||||
test "$(git rev-parse HEAD^2^1^1)" = "$(git rev-parse H1)"
|
||||
'
|
||||
|
||||
# On the other hand if rebase from E1 which is within one branch,
|
||||
# then the other branch stays:
|
||||
# A1---B1---E1---F1---G1
|
||||
# \ \ /
|
||||
# \ \--C1---D1--/
|
||||
# \ \
|
||||
# H1-----F3-----G3
|
||||
|
||||
test_expect_success 'rebase from E1 onto H1' '
|
||||
git checkout G1 &&
|
||||
git rebase -p --onto H1 E1 &&
|
||||
test "$(git rev-parse HEAD^1^1)" = "$(git rev-parse H1)" &&
|
||||
test "$(git rev-parse HEAD^2)" = "$(git rev-parse D1)"
|
||||
'
|
||||
|
||||
# And the same if we rebase from a commit in the second-parent branch.
|
||||
# A1---B1---E1---F1----G1
|
||||
# \ \ \ /
|
||||
# \ \--C1---D1-\-/
|
||||
# \ \
|
||||
# H1------D3------G4
|
||||
|
||||
test_expect_success 'rebase from C1 onto H1' '
|
||||
git checkout G1 &&
|
||||
git rev-list --first-parent --pretty=oneline C1..G1 &&
|
||||
git rebase -p --onto H1 C1 &&
|
||||
test "$(git rev-parse HEAD^2^1)" = "$(git rev-parse H1)" &&
|
||||
test "$(git rev-parse HEAD^1)" = "$(git rev-parse F1)"
|
||||
'
|
||||
|
||||
test_done
|
84
t/t4038-diff-combined.sh
Executable file
84
t/t4038-diff-combined.sh
Executable file
@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='combined diff'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
setup_helper () {
|
||||
one=$1 branch=$2 side=$3 &&
|
||||
|
||||
git branch $side $branch &&
|
||||
for l in $one two three fyra
|
||||
do
|
||||
echo $l
|
||||
done >file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m $branch &&
|
||||
git checkout $side &&
|
||||
for l in $one two three quatro
|
||||
do
|
||||
echo $l
|
||||
done >file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m $side &&
|
||||
test_must_fail git merge $branch &&
|
||||
for l in $one three four
|
||||
do
|
||||
echo $l
|
||||
done >file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m "merge $branch into $side"
|
||||
}
|
||||
|
||||
verify_helper () {
|
||||
it=$1 &&
|
||||
|
||||
# Ignore lines that were removed only from the other parent
|
||||
sed -e '
|
||||
1,/^@@@/d
|
||||
/^ -/d
|
||||
s/^\(.\)./\1/
|
||||
' "$it" >"$it.actual.1" &&
|
||||
sed -e '
|
||||
1,/^@@@/d
|
||||
/^- /d
|
||||
s/^.\(.\)/\1/
|
||||
' "$it" >"$it.actual.2" &&
|
||||
|
||||
git diff "$it^" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.1" &&
|
||||
test_cmp "$it.expect.1" "$it.actual.1" &&
|
||||
|
||||
git diff "$it^2" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.2" &&
|
||||
test_cmp "$it.expect.2" "$it.actual.2"
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
>file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m initial &&
|
||||
|
||||
git branch withone &&
|
||||
git branch sansone &&
|
||||
|
||||
git checkout withone &&
|
||||
setup_helper one withone sidewithone &&
|
||||
|
||||
git checkout sansone &&
|
||||
setup_helper "" sansone sidesansone
|
||||
'
|
||||
|
||||
test_expect_success 'check combined output (1)' '
|
||||
git show sidewithone -- >sidewithone &&
|
||||
verify_helper sidewithone
|
||||
'
|
||||
|
||||
test_expect_failure 'check combined output (2)' '
|
||||
git show sidesansone -- >sidesansone &&
|
||||
verify_helper sidesansone
|
||||
'
|
||||
|
||||
test_done
|
@ -148,4 +148,26 @@ do
|
||||
done
|
||||
done
|
||||
|
||||
create_patch () {
|
||||
sed -e "s/_/ /" <<-\EOF
|
||||
diff --git a/target b/target
|
||||
index e69de29..8bd6648 100644
|
||||
--- a/target
|
||||
+++ b/target
|
||||
@@ -0,0 +1,3 @@
|
||||
+An empty line follows
|
||||
+
|
||||
+A line with trailing whitespace and no newline_
|
||||
\ No newline at end of file
|
||||
EOF
|
||||
}
|
||||
|
||||
test_expect_success 'trailing whitespace & no newline at the end of file' '
|
||||
>target &&
|
||||
create_patch >patch-file &&
|
||||
git apply --whitespace=fix patch-file &&
|
||||
grep "newline$" target &&
|
||||
grep "^$" target
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -149,6 +149,26 @@ test_expect_success 'git log --follow' '
|
||||
|
||||
'
|
||||
|
||||
cat > expect << EOF
|
||||
804a787 sixth
|
||||
394ef78 fifth
|
||||
5d31159 fourth
|
||||
EOF
|
||||
test_expect_success 'git log --no-walk <commits> sorts by commit time' '
|
||||
git log --no-walk --oneline 5d31159 804a787 394ef78 > actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
cat > expect << EOF
|
||||
5d31159 fourth
|
||||
804a787 sixth
|
||||
394ef78 fifth
|
||||
EOF
|
||||
test_expect_success 'git show <commits> leaves list of commits as given' '
|
||||
git show --oneline -s 5d31159 804a787 394ef78 > actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'setup case sensitivity tests' '
|
||||
echo case >one &&
|
||||
test_tick &&
|
||||
|
@ -119,4 +119,24 @@ test_expect_success 'quickfetch should not copy from alternate' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'quickfetch should handle ~1000 refs (on Windows)' '
|
||||
|
||||
git gc &&
|
||||
head=$(git rev-parse HEAD) &&
|
||||
branchprefix="$head refs/heads/branch" &&
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for j in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for k in 0 1 2 3 4 5 6 7 8 9; do
|
||||
echo "$branchprefix$i$j$k" >> .git/packed-refs
|
||||
done
|
||||
done
|
||||
done &&
|
||||
(
|
||||
cd cloned &&
|
||||
git fetch &&
|
||||
git fetch
|
||||
)
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -9,6 +9,11 @@ test_description='Per branch config variables affects "git fetch".
|
||||
|
||||
D=`pwd`
|
||||
|
||||
test_bundle_object_count () {
|
||||
git verify-pack -v "$1" >verify.out &&
|
||||
test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
echo >file original &&
|
||||
git add file &&
|
||||
@ -146,6 +151,7 @@ test_expect_success 'unbundle 1' '
|
||||
test_must_fail git fetch "$D/bundle1" master:master
|
||||
'
|
||||
|
||||
|
||||
test_expect_success 'bundle 1 has only 3 files ' '
|
||||
cd "$D" &&
|
||||
(
|
||||
@ -156,8 +162,7 @@ test_expect_success 'bundle 1 has only 3 files ' '
|
||||
cat
|
||||
) <bundle1 >bundle.pack &&
|
||||
git index-pack bundle.pack &&
|
||||
verify=$(git verify-pack -v bundle.pack) &&
|
||||
test 4 = $(echo "$verify" | wc -l)
|
||||
test_bundle_object_count bundle.pack 3
|
||||
'
|
||||
|
||||
test_expect_success 'unbundle 2' '
|
||||
@ -180,7 +185,7 @@ test_expect_success 'bundle does not prerequisite objects' '
|
||||
cat
|
||||
) <bundle3 >bundle.pack &&
|
||||
git index-pack bundle.pack &&
|
||||
test 4 = $(git verify-pack -v bundle.pack | wc -l)
|
||||
test_bundle_object_count bundle.pack 3
|
||||
'
|
||||
|
||||
test_expect_success 'bundle should be able to create a full history' '
|
||||
|
@ -149,5 +149,17 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
|
||||
test_must_fail git show $csha1
|
||||
'
|
||||
|
||||
test_expect_success 'objects made unreachable by grafts only are kept' '
|
||||
test_tick &&
|
||||
git commit --allow-empty -m "commit 4" &&
|
||||
H0=$(git rev-parse HEAD) &&
|
||||
H1=$(git rev-parse HEAD^) &&
|
||||
H2=$(git rev-parse HEAD^^) &&
|
||||
echo "$H0 $H2" > .git/info/grafts &&
|
||||
git reflog expire --expire=now --expire-unreachable=now --all &&
|
||||
git repack -a -d &&
|
||||
git cat-file -t $H1
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
|
@ -4,7 +4,7 @@ test_description='git blame encoding conversion'
|
||||
. ./test-lib.sh
|
||||
|
||||
. "$TEST_DIRECTORY"/t8005/utf8.txt
|
||||
. "$TEST_DIRECTORY"/t8005/iso8859-5.txt
|
||||
. "$TEST_DIRECTORY"/t8005/euc-japan.txt
|
||||
. "$TEST_DIRECTORY"/t8005/sjis.txt
|
||||
|
||||
test_expect_success 'setup the repository' '
|
||||
@ -13,10 +13,10 @@ test_expect_success 'setup the repository' '
|
||||
git add file &&
|
||||
git commit --author "$UTF8_NAME <utf8@localhost>" -m "$UTF8_MSG" &&
|
||||
|
||||
echo "ISO-8859-5 LINE" >> file &&
|
||||
echo "EUC-JAPAN LINE" >> file &&
|
||||
git add file &&
|
||||
git config i18n.commitencoding ISO8859-5 &&
|
||||
git commit --author "$ISO8859_5_NAME <iso8859-5@localhost>" -m "$ISO8859_5_MSG" &&
|
||||
git config i18n.commitencoding eucJP &&
|
||||
git commit --author "$EUC_JAPAN_NAME <euc-japan@localhost>" -m "$EUC_JAPAN_MSG" &&
|
||||
|
||||
echo "SJIS LINE" >> file &&
|
||||
git add file &&
|
||||
@ -41,17 +41,17 @@ test_expect_success \
|
||||
'
|
||||
|
||||
cat >expected <<EOF
|
||||
author $ISO8859_5_NAME
|
||||
summary $ISO8859_5_MSG
|
||||
author $ISO8859_5_NAME
|
||||
summary $ISO8859_5_MSG
|
||||
author $ISO8859_5_NAME
|
||||
summary $ISO8859_5_MSG
|
||||
author $EUC_JAPAN_NAME
|
||||
summary $EUC_JAPAN_MSG
|
||||
author $EUC_JAPAN_NAME
|
||||
summary $EUC_JAPAN_MSG
|
||||
author $EUC_JAPAN_NAME
|
||||
summary $EUC_JAPAN_MSG
|
||||
EOF
|
||||
|
||||
test_expect_success \
|
||||
'blame respects i18n.logoutputencoding' '
|
||||
git config i18n.logoutputencoding ISO8859-5 &&
|
||||
git config i18n.logoutputencoding eucJP &&
|
||||
git blame --incremental file | \
|
||||
egrep "^(author|summary) " > actual &&
|
||||
test_cmp actual expected
|
||||
@ -76,8 +76,8 @@ test_expect_success \
|
||||
cat >expected <<EOF
|
||||
author $SJIS_NAME
|
||||
summary $SJIS_MSG
|
||||
author $ISO8859_5_NAME
|
||||
summary $ISO8859_5_MSG
|
||||
author $EUC_JAPAN_NAME
|
||||
summary $EUC_JAPAN_MSG
|
||||
author $UTF8_NAME
|
||||
summary $UTF8_MSG
|
||||
EOF
|
||||
|
2
t/t8005/euc-japan.txt
Normal file
2
t/t8005/euc-japan.txt
Normal file
@ -0,0 +1,2 @@
|
||||
EUC_JAPAN_NAME="山田 太郎"
|
||||
EUC_JAPAN_MSG="ブレームのテストです。"
|
@ -1,2 +1,2 @@
|
||||
SJIS_NAME="„I„r„p„~ „P„u„„„‚„€„r„y„‰ „R„y„t„€„‚„€„r"
|
||||
SJIS_MSG="„S„u„ƒ„„„€„r„€„u „ƒ„€„€„q„‹„u„~„y„u"
|
||||
SJIS_NAME="山田 太郎"
|
||||
SJIS_MSG="ブレームのテストです。"
|
||||
|
@ -1,2 +1,2 @@
|
||||
UTF8_NAME="Иван Петрович Сидоров"
|
||||
UTF8_MSG="Тестовое сообщение"
|
||||
UTF8_NAME="山田 太郎"
|
||||
UTF8_MSG="ブレームのテストです。"
|
||||
|
@ -99,22 +99,22 @@ test_expect_success 'Multiple branch or tag paths require -d' '
|
||||
|
||||
test_expect_success 'create new branches and tags' '
|
||||
( cd git_project &&
|
||||
git svn branch -m "New branch 1" -d project/b_one New1 ) &&
|
||||
git svn branch -m "New branch 1" -d b_one New1 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e b_one/New1/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn branch -m "New branch 2" -d project/b_two New2 ) &&
|
||||
git svn branch -m "New branch 2" -d b_two New2 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e b_two/New2/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) &&
|
||||
git svn branch -t -m "New tag 1" -d tags_A Tag1 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e tags_A/Tag1/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn tag -m "New tag 2" -d project/tags_B Tag2 ) &&
|
||||
git svn tag -m "New tag 2" -d tags_B Tag2 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e tags_B/Tag2/a.file )
|
||||
'
|
32
t/t9142-git-svn-shallow-clone.sh
Executable file
32
t/t9142-git-svn-shallow-clone.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Eric Wong
|
||||
#
|
||||
|
||||
test_description='git svn shallow clone'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'setup test repository' '
|
||||
svn_cmd mkdir -m "create standard layout" \
|
||||
"$svnrepo"/trunk "$svnrepo"/branches "$svnrepo"/tags &&
|
||||
svn_cmd cp -m "branch off trunk" \
|
||||
"$svnrepo"/trunk "$svnrepo"/branches/a &&
|
||||
svn_cmd co "$svnrepo"/branches/a &&
|
||||
(
|
||||
cd a &&
|
||||
> foo &&
|
||||
svn_cmd add foo &&
|
||||
svn_cmd commit -m "add foo"
|
||||
)
|
||||
'
|
||||
|
||||
start_httpd
|
||||
|
||||
test_expect_success 'clone trunk with "-r HEAD"' '
|
||||
git svn clone -r HEAD "$svnrepo/trunk" g &&
|
||||
( cd g && git rev-parse --symbolic --verify HEAD )
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
|
||||
test_done
|
53
t/t9143-git-svn-gc.sh
Executable file
53
t/t9143-git-svn-gc.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Robert Allan Zeh
|
||||
|
||||
test_description='git svn gc basic tests'
|
||||
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'setup directories and test repo' '
|
||||
mkdir import &&
|
||||
mkdir tmp &&
|
||||
echo "Sample text for Subversion repository." > import/test.txt &&
|
||||
svn_cmd import -m "import for git svn" import "$svnrepo" > /dev/null
|
||||
'
|
||||
|
||||
test_expect_success 'checkout working copy from svn' \
|
||||
'svn_cmd co "$svnrepo" test_wc'
|
||||
|
||||
test_expect_success 'set some properties to create an unhandled.log file' '
|
||||
(
|
||||
cd test_wc &&
|
||||
svn_cmd propset foo bar test.txt &&
|
||||
svn_cmd commit -m "property set"
|
||||
)'
|
||||
|
||||
test_expect_success 'Setup repo' 'git svn init "$svnrepo"'
|
||||
|
||||
test_expect_success 'Fetch repo' 'git svn fetch'
|
||||
|
||||
test_expect_success 'make backup copy of unhandled.log' '
|
||||
cp .git/svn/git-svn/unhandled.log tmp
|
||||
'
|
||||
|
||||
test_expect_success 'create leftover index' '> .git/svn/git-svn/index'
|
||||
|
||||
test_expect_success 'git svn gc runs' 'git svn gc'
|
||||
|
||||
test_expect_success 'git svn index removed' '! test -f .git/svn/git-svn/index'
|
||||
|
||||
if perl -MCompress::Zlib -e 0 2>/dev/null
|
||||
then
|
||||
test_expect_success 'git svn gc produces a valid gzip file' '
|
||||
gunzip .git/svn/git-svn/unhandled.log.gz
|
||||
'
|
||||
else
|
||||
say "Perl Compress::Zlib unavailable, skipping gunzip test"
|
||||
fi
|
||||
|
||||
test_expect_success 'git svn gc does not change unhandled.log files' '
|
||||
test_cmp .git/svn/git-svn/unhandled.log tmp/unhandled.log
|
||||
'
|
||||
|
||||
test_done
|
@ -288,6 +288,27 @@ test_expect_success 'check files before directories' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 're-commit a removed filename which remains in CVS attic' '
|
||||
|
||||
(cd "$CVSWORK" &&
|
||||
echo >attic_gremlin &&
|
||||
cvs -Q add attic_gremlin &&
|
||||
cvs -Q ci -m "added attic_gremlin" &&
|
||||
rm attic_gremlin &&
|
||||
cvs -Q rm attic_gremlin &&
|
||||
cvs -Q ci -m "removed attic_gremlin") &&
|
||||
|
||||
echo > attic_gremlin &&
|
||||
git add attic_gremlin &&
|
||||
git commit -m "Added attic_gremlin" &&
|
||||
git cvsexportcommit -w "$CVSWORK" -c HEAD &&
|
||||
(cd "$CVSWORK"; cvs -Q update -d) &&
|
||||
test -f "$CVSWORK/attic_gremlin"
|
||||
'
|
||||
|
||||
# the state of the CVS sandbox may be indeterminate for ' space'
|
||||
# after this test on some platforms / with some versions of CVS
|
||||
# consider adding new tests above this point
|
||||
test_expect_success 'commit a file with leading spaces in the name' '
|
||||
|
||||
echo space > " space" &&
|
||||
@ -295,7 +316,7 @@ test_expect_success 'commit a file with leading spaces in the name' '
|
||||
git commit -m "Add a file with a leading space" &&
|
||||
id=$(git rev-parse HEAD) &&
|
||||
git cvsexportcommit -w "$CVSWORK" -c $id &&
|
||||
check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
|
||||
check_entries "$CVSWORK" " space/1.1/|DS/1.1/|attic_gremlin/1.3/|release-notes/1.2/" &&
|
||||
test_cmp "$CVSWORK/ space" " space"
|
||||
|
||||
'
|
||||
@ -317,22 +338,4 @@ test_expect_success 'use the same checkout for Git and CVS' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 're-commit a removed filename which remains in CVS attic' '
|
||||
|
||||
(cd "$CVSWORK" &&
|
||||
echo >attic_gremlin &&
|
||||
cvs -Q add attic_gremlin &&
|
||||
cvs -Q ci -m "added attic_gremlin" &&
|
||||
rm attic_gremlin &&
|
||||
cvs -Q rm attic_gremlin &&
|
||||
cvs -Q ci -m "removed attic_gremlin") &&
|
||||
|
||||
echo > attic_gremlin &&
|
||||
git add attic_gremlin &&
|
||||
git commit -m "Added attic_gremlin" &&
|
||||
git cvsexportcommit -w "$CVSWORK" -c HEAD &&
|
||||
(cd "$CVSWORK"; cvs -Q update -d) &&
|
||||
test -f "$CVSWORK/attic_gremlin"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -262,6 +262,94 @@ test_expect_success 'cope with tagger-less tags' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'setup for limiting exports by PATH' '
|
||||
mkdir limit-by-paths &&
|
||||
cd limit-by-paths &&
|
||||
git init &&
|
||||
echo hi > there &&
|
||||
git add there &&
|
||||
git commit -m "First file" &&
|
||||
echo foo > bar &&
|
||||
git add bar &&
|
||||
git commit -m "Second file" &&
|
||||
git tag -a -m msg mytag &&
|
||||
echo morefoo >> bar &&
|
||||
git add bar &&
|
||||
git commit -m "Change to second file" &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
cat > limit-by-paths/expected << EOF
|
||||
blob
|
||||
mark :1
|
||||
data 3
|
||||
hi
|
||||
|
||||
reset refs/tags/mytag
|
||||
commit refs/tags/mytag
|
||||
mark :2
|
||||
author A U Thor <author@example.com> 1112912713 -0700
|
||||
committer C O Mitter <committer@example.com> 1112912713 -0700
|
||||
data 11
|
||||
First file
|
||||
M 100644 :1 there
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_success 'dropping tag of filtered out object' '
|
||||
cd limit-by-paths &&
|
||||
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
|
||||
test_cmp output expected &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
cat >> limit-by-paths/expected << EOF
|
||||
tag mytag
|
||||
from :2
|
||||
tagger C O Mitter <committer@example.com> 1112912713 -0700
|
||||
data 4
|
||||
msg
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_success 'rewriting tag of filtered out object' '
|
||||
cd limit-by-paths &&
|
||||
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
|
||||
test_cmp output expected &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
cat > limit-by-paths/expected << EOF
|
||||
blob
|
||||
mark :1
|
||||
data 4
|
||||
foo
|
||||
|
||||
blob
|
||||
mark :2
|
||||
data 3
|
||||
hi
|
||||
|
||||
reset refs/heads/master
|
||||
commit refs/heads/master
|
||||
mark :3
|
||||
author A U Thor <author@example.com> 1112912713 -0700
|
||||
committer C O Mitter <committer@example.com> 1112912713 -0700
|
||||
data 12
|
||||
Second file
|
||||
M 100644 :1 bar
|
||||
M 100644 :2 there
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_failure 'no exact-ref revisions included' '
|
||||
cd limit-by-paths &&
|
||||
git fast-export master~2..master~1 > output &&
|
||||
test_cmp output expected &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
|
||||
test_expect_success 'set-up a few more tags for tag export tests' '
|
||||
git checkout -f master &&
|
||||
HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` &&
|
||||
@ -271,8 +359,14 @@ test_expect_success 'set-up a few more tags for tag export tests' '
|
||||
git tag -a tag-obj_tag-obj -m "tagging a tag" tree_tag-obj
|
||||
'
|
||||
|
||||
test_expect_success 'tree_tag' '
|
||||
mkdir result &&
|
||||
(cd result && git init) &&
|
||||
git fast-export tree_tag > fe-stream &&
|
||||
(cd result && git fast-import < ../fe-stream)
|
||||
'
|
||||
|
||||
# NEEDSWORK: not just check return status, but validate the output
|
||||
test_expect_success 'tree_tag' 'git fast-export tree_tag'
|
||||
test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj'
|
||||
test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag'
|
||||
test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj'
|
||||
|
@ -128,7 +128,7 @@ static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_o
|
||||
|
||||
static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_options *o)
|
||||
{
|
||||
struct cache_entry *src[5] = { ce, };
|
||||
struct cache_entry *src[5] = { ce, NULL, };
|
||||
|
||||
o->pos++;
|
||||
if (ce_stage(ce)) {
|
||||
@ -551,7 +551,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
|
||||
memset(&d, 0, sizeof(d));
|
||||
if (o->dir)
|
||||
d.exclude_per_dir = o->dir->exclude_per_dir;
|
||||
i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
|
||||
i = read_directory(&d, pathbuf, namelen+1, NULL);
|
||||
if (i)
|
||||
return o->gently ? -1 :
|
||||
error(ERRORMSG(o, not_uptodate_dir), ce->name);
|
||||
@ -999,12 +999,12 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
|
||||
return error("Cannot do a oneway merge of %d trees",
|
||||
o->merge_size);
|
||||
|
||||
if (!a)
|
||||
if (!a || a == o->df_conflict_entry)
|
||||
return deleted_entry(old, old, o);
|
||||
|
||||
if (old && same(old, a)) {
|
||||
int update = 0;
|
||||
if (o->reset) {
|
||||
if (o->reset && !ce_uptodate(old)) {
|
||||
struct stat st;
|
||||
if (lstat(old->name, &st) ||
|
||||
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID))
|
||||
|
2
walker.c
2
walker.c
@ -245,7 +245,7 @@ void walker_targets_free(int targets, char **target, const char **write_ref)
|
||||
{
|
||||
while (targets--) {
|
||||
free(target[targets]);
|
||||
if (write_ref && write_ref[targets])
|
||||
if (write_ref)
|
||||
free((char *) write_ref[targets]);
|
||||
}
|
||||
}
|
||||
|
7
ws.c
7
ws.c
@ -261,12 +261,11 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro
|
||||
/*
|
||||
* Strip trailing whitespace
|
||||
*/
|
||||
if ((ws_rule & WS_TRAILING_SPACE) &&
|
||||
(2 <= len && isspace(src[len-2]))) {
|
||||
if (src[len - 1] == '\n') {
|
||||
if (ws_rule & WS_TRAILING_SPACE) {
|
||||
if (0 < len && src[len - 1] == '\n') {
|
||||
add_nl_to_tail = 1;
|
||||
len--;
|
||||
if (1 < len && src[len - 1] == '\r') {
|
||||
if (0 < len && src[len - 1] == '\r') {
|
||||
add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
|
||||
len--;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ static void wt_status_print_untracked(struct wt_status *s)
|
||||
DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
|
||||
setup_standard_excludes(&dir);
|
||||
|
||||
read_directory(&dir, ".", "", 0, NULL);
|
||||
fill_directory(&dir, NULL);
|
||||
for(i = 0; i < dir.nr; i++) {
|
||||
struct dir_entry *ent = dir.entries[i];
|
||||
if (!cache_name_is_other(ent->name, ent->len))
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define XDL_MAX_COST_MIN 256
|
||||
#define XDL_HEUR_MIN_COST 256
|
||||
#define XDL_LINE_MAX (long)((1UL << (8 * sizeof(long) - 1)) - 1)
|
||||
#define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
|
||||
#define XDL_SNAKE_CNT 20
|
||||
#define XDL_K_HEUR 4
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user