Merge commit 'mingw/master' into work/merge-mingw-master-2

Conflicts:

	Makefile
	git-clone.sh
	git-gui/README
	git-gui/git-gui.pot
	git-gui/glossary/Makefile
	git-gui/glossary/de.po
	git-gui/glossary/git-gui-glossary.pot
	git-gui/glossary/git-gui-glossary.txt
	git-gui/glossary/txt-to-pot.sh
	git-gui/glossary/zh_cn.po
	git-gui/lib/commit.tcl
	git-gui/lib/console.tcl
	git-gui/po/README
	git-gui/po/git-gui.pot
	git-gui/po/glossary/Makefile
	git-gui/po/glossary/de.po
	git-gui/po/glossary/git-gui-glossary.pot
	git-gui/po/glossary/git-gui-glossary.txt
	git-gui/po/glossary/txt-to-pot.sh
	git-gui/po/glossary/zh_cn.po
	po/README
	po/git-gui.pot
	po/glossary/Makefile
	po/glossary/de.po
	po/glossary/git-gui-glossary.pot
	po/glossary/git-gui-glossary.txt
	po/glossary/txt-to-pot.sh
	po/glossary/zh_cn.po

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
This commit is contained in:
Steffen Prohaska
2007-11-25 14:00:20 +01:00
125 changed files with 3785 additions and 1760 deletions

View File

@@ -4,18 +4,45 @@ GIT v1.5.3.6 Release Notes
Fixes since v1.5.3.5
--------------------
* git-cvsexportcommit handles root commits better;
* git-cvsexportcommit handles root commits better.
* git-svn dcommit used to clobber when sending a series of
patches;
patches.
* git-svn dcommit failed after attempting to rebase when
started with a dirty index; now it stops upfront.
* git-grep sometimes refused to work when your index was
unmerged;
unmerged.
* "git-grep -A1 -B2" acted as if it was told to run "git -A1 -B21".
* git-hash-object did not honor configuration variables, such as
core.compression.
* git-index-pack choked on a huge pack on 32-bit machines, even when
large file offsets are supported.
* atom feeds from git-web said "10" for the month of November.
* a memory leak in commit walker was plugged.
* When git-send-email inserted the original author's From:
address in body, it did not mark the message with
Content-type: as needed.
* git-revert and git-cherry-pick incorrectly refused to start
when the work tree was dirty.
* git-clean did not honor core.excludesfile configuration.
* git-add mishandled ".gitignore" files when applying them to
subdirectories.
* While importing a too branchy history, git-fastimport did not
honor delta depth limit properly.
* Support for zlib implementations that lack ZLIB_VERNUM and definition
of deflateBound() has been added.
* Quite a lot of documentation clarifications.
--
exec >/var/tmp/1
O=v1.5.3.5-32-gcb6c162
echo O=`git describe refs/heads/maint`
git shortlog --no-merges $O..refs/heads/maint

View File

@@ -32,6 +32,11 @@ Updates since v1.5.3
(read: safer than the usual one) after the user accumulates
too many loose objects.
* You need to explicitly set clean.requireForce to "false" to allow
git-clean without -f to do any damage (lack of the configuration
variable used to mean "do not require", but we now use the safer
default).
* git-push has been rewritten in C.
* git-push learned --dry-run option to show what would happen
@@ -52,11 +57,39 @@ Updates since v1.5.3
* git-lost-found was deprecated in favor of git-fsck's --lost-found
option.
* "git log" learned --early-output option to help interactive
GUI implementations.
* git-svnimport was removed in favor of git-svn.
* git-bisect learned "skip" action to mark untestable commits.
* rename detection diff family, while detecting exact matches,
* git-format-patch learned "format.numbered" configuration variable
to automatically turn --numbered option on when more than one
commits are formatted.
* git-ls-files learned "--exclude-standard" to use the canned
set of exclude files.
* git-rebase now detaches head during its operation, so after a
successful "git rebase" operation, the reflog entry branch@{1}
for the current branch points at the commit before the rebase
was started.
* "git-tag -a -f existing" begins the editor session using the
existing annotation message.
* "git cvsexportcommit" learned -w option to specify and switch
to the CVS working directory.
* "git checkout" from a subdirectory learned to use "../path"
to allow checking out a path outside the current directory
without cd'ing up.
* Output processing for '--pretty=format:<user format>' has
been optimized.
* Rename detection diff family, while detecting exact matches,
has been greatly optimized.
* Example update and post-receive hooks have been improved.
@@ -77,8 +110,15 @@ Fixes since v1.5.3
All of the fixes in v1.5.3 maintenance series are included in
this release, unless otherwise noted.
* git-svn talking with the SVN over http will correctly quote branch
and project names.
* "git rev-list --objects A..B" choked when the lower boundary
of the range involved a subproject. This fix is also queued
for 'maint' (but not in there yet).
--
exec >/var/tmp/1
O=v1.5.3.5-618-g5d4138a
O=v1.5.3.6-727-g5d3d1ca
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint

View File

@@ -226,13 +226,15 @@ core.compression::
An integer -1..9, indicating a default compression level.
-1 is the zlib default. 0 means no compression,
and 1..9 are various speed/size tradeoffs, 9 being slowest.
If set, this provides a default to other compression variables,
such as 'core.loosecompression' and 'pack.compression'.
core.loosecompression::
An integer -1..9, indicating the compression level for objects that
are not in a pack file. -1 is the zlib default. 0 means no
compression, and 1..9 are various speed/size tradeoffs, 9 being
slowest. If not set, defaults to core.compression. If that is
not set, defaults to 0 (best speed).
not set, defaults to 1 (best speed).
core.packedGitWindowSize::
Number of bytes of a pack file to map into memory in a
@@ -648,7 +650,9 @@ pack.compression::
in a pack file. -1 is the zlib default. 0 means no
compression, and 1..9 are various speed/size tradeoffs, 9 being
slowest. If not set, defaults to core.compression. If that is
not set, defaults to -1.
not set, defaults to -1, the zlib default, which is "a default
compromise between speed and compression (currently equivalent
to level 6)."
pack.deltaCacheSize::
The maximum memory in bytes used for caching deltas in

View File

@@ -1,5 +1,25 @@
// Please don't remove this comment as asciidoc behaves badly when
// the first non-empty line is ifdef/ifndef. The symptom is that
// without this comment the <git-diff-core> attribute conditionally
// defined below ends up being defined unconditionally.
// Last checked with asciidoc 7.0.2.
ifndef::git-format-patch[]
ifndef::git-diff[]
:git-diff-core: 1
endif::git-diff[]
endif::git-format-patch[]
ifdef::git-format-patch[]
-p::
Generate patch (see section on generating patches)
Generate patches without diffstat.
endif::git-format-patch[]
ifndef::git-format-patch[]
-p::
Generate patch (see section on generating patches).
{git-diff? This is the default.}
endif::git-format-patch[]
-u::
Synonym for "-p".
@@ -13,6 +33,7 @@
--raw::
Generate the raw format.
{git-diff-core? This is the default.}
--patch-with-raw::
Synonym for "-p --raw".
@@ -41,6 +62,7 @@
--patch-with-stat::
Synonym for "-p --stat".
{git-format-patch? This is the default.}
-z::
NUL-line termination on output. This affects the --raw

View File

@@ -130,6 +130,7 @@ OPTIONS
for "host.xz:foo/.git"). Cloning into an existing directory
is not allowed.
:git-clone: 1
include::urls.txt[]
Examples

View File

@@ -75,6 +75,7 @@ and the range notations ("<commit>..<commit>" and
OPTIONS
-------
:git-diff: 1
include::diff-options.txt[]
<path>...::

View File

@@ -66,6 +66,7 @@ reference.
OPTIONS
-------
:git-format-patch: 1
include::diff-options.txt[]
-<n>::

View File

@@ -3,7 +3,7 @@ git-get-tar-commit-id(1)
NAME
----
git-get-tar-commit-id - Extract commit ID from an archive created using git-tar-tree
git-get-tar-commit-id - Extract commit ID from an archive created using git-archive
SYNOPSIS
@@ -19,7 +19,7 @@ runtime is not influenced by the size of <tarfile> very much.
If no commit ID is found, git-get-tar-commit-id quietly exists with a
return code of 1. This can happen if <tarfile> had not been created
using git-archive or if the <treeish> parameter of git-archive had been
using git-archive or if the first parameter of git-archive had been
a tree ID instead of a commit ID or tag.

View File

@@ -15,6 +15,7 @@ SYNOPSIS
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
[--exclude-standard]
[--error-unmatch] [--with-tree=<tree-ish>]
[--full-name] [--abbrev] [--] [<file>]\*
@@ -77,6 +78,10 @@ OPTIONS
read additional exclude patterns that apply only to the
directory and its subdirectories in <file>.
--exclude-standard::
Add the standard git exclusions: .git/info/exclude, .gitignore
in each directory, and the user's global exclusion file.
--error-unmatch::
If any <file> does not appear in the index, treat this as an
error (return 1).

View File

@@ -19,7 +19,7 @@ depending on the subcommand:
git reflog expire [--dry-run] [--stale-fix] [--verbose]
[--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...
git reflog [show] [log-options]
git reflog [show] [log-options] [<ref>]
Reflog is a mechanism to record when the tip of branches are
updated. This command is to manage the information recorded in it.
@@ -32,9 +32,16 @@ directly by the end users -- instead, see gitlink:git-gc[1].
The subcommand "show" (which is also the default, in the absence of any
subcommands) will take all the normal log options, and show the log of
`HEAD`, which will cover all recent actions, including branch switches.
It is basically an alias for 'git log -g --abbrev-commit
--pretty=oneline', see gitlink:git-log[1].
the reference provided in the command-line (or `HEAD`, by default).
The reflog will cover all recent actions (HEAD reflog records branch switching
as well). It is an alias for 'git log -g --abbrev-commit --pretty=oneline';
see gitlink:git-log[1].
The reflog is useful in various git commands, to specify the old value
of a reference. For example, `HEAD@\{2\}` means "where HEAD used to be
two moves ago", `master@\{one.week.ago\}` means "where master used to
point to one week ago", and so on. See gitlink:git-rev-parse[1] for
more details.
OPTIONS

View File

@@ -101,7 +101,7 @@ $ git remote
origin
$ git branch -r
origin/master
$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git
$ git remote add linux-nfs git://linux-nfs.org/pub/linux/nfs-2.6.git
$ git remote
linux-nfs
origin

View File

@@ -23,6 +23,13 @@ distinguish between them.
OPTIONS
-------
--parseopt::
Use `git-rev-parse` in option parsing mode (see PARSEOPT section below).
--keep-dash-dash::
Only meaningful in `--parseopt` mode. Tells the option parser to echo
out the first `--` met instead of skipping it.
--revs-only::
Do not output flags and parameters not meant for
`git-rev-list` command.
@@ -288,10 +295,75 @@ Here are a handful examples:
C^@ I J F
F^! D G H D F
PARSEOPT
--------
In `--parseopt` mode, `git-rev-parse` helps massaging options to bring to shell
scripts the same facilities C builtins have. It works as an option normalizer
(e.g. splits single switches aggregate values), a bit like `getopt(1)` does.
It takes on the standard input the specification of the options to parse and
understand, and echoes on the standard output a line suitable for `sh(1)` `eval`
to replace the arguments with normalized ones. In case of error, it outputs
usage on the standard error stream, and exits with code 129.
Input Format
~~~~~~~~~~~~
`git-rev-parse --parseopt` input format is fully text based. It has two parts,
separated by a line that contains only `--`. The lines before the separator
(should be more than one) are used for the usage.
The lines after the separator describe the options.
Each line of options has this format:
------------
<opt_spec><arg_spec>? SP+ help LF
------------
`<opt_spec>`::
its format is the short option character, then the long option name
separated by a comma. Both parts are not required, though at least one
is necessary. `h,help`, `dry-run` and `f` are all three correct
`<opt_spec>`.
`<arg_spec>`::
an `<arg_spec>` tells the option parser if the option has an argument
(`=`), an optional one (`?` though its use is discouraged) or none
(no `<arg_spec>` in that case).
The remainder of the line, after stripping the spaces, is used
as the help associated to the option.
Blank lines are ignored, and lines that don't match this specification are used
as option group headers (start the line with a space to create such
lines on purpose).
Example
~~~~~~~
------------
OPTS_SPEC="\
some-command [options] <args>...
some-command does foo and bar!
--
h,help show the help
foo some nifty option --foo
bar= some cool option --bar with an argument
An option group Header
C? option C with an optional argument"
eval `echo "$OPTS_SPEC" | git-rev-parse --parseopt -- "$@" || echo exit $?`
------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <junkio@cox.net>
Written by Linus Torvalds <torvalds@osdl.org> .
Junio C Hamano <junkio@cox.net> and Pierre Habouzit <madcoder@debian.org>
Documentation
--------------

View File

@@ -193,6 +193,12 @@ Any other arguments are passed directly to `git log'
repository (that has been init-ed with git-svn).
The -r<revision> option is required for this.
'info'::
Shows information about a file or directory similar to what
`svn info' provides. Does not currently support a -r/--revision
argument. Use the --url option to output only the value of the
'URL:' field.
--
OPTIONS

View File

@@ -46,6 +46,7 @@ Documentation for older releases are available here:
* link:v1.5.3/git.html[documentation for release 1.5.3]
* release notes for
link:RelNotes-1.5.3.6.txt[1.5.3.6],
link:RelNotes-1.5.3.5.txt[1.5.3.5],
link:RelNotes-1.5.3.4.txt[1.5.3.4],
link:RelNotes-1.5.3.3.txt[1.5.3.3],

View File

@@ -0,0 +1,277 @@
From: Junio C Hamano <gitster@pobox.com>
Date: Wed, 21 Nov 2007 16:32:55 -0800
Subject: Addendum to "MaintNotes"
Abstract: Imagine that git development is racing along as usual, when our friendly
neighborhood maintainer is struck down by a wayward bus. Out of the
hordes of suckers (loyal developers), you have been tricked (chosen) to
step up as the new maintainer. This howto will show you "how to" do it.
The maintainer's git time is spent on three activities.
- Communication (60%)
Mailing list discussions on general design, fielding user
questions, diagnosing bug reports; reviewing, commenting on,
suggesting alternatives to, and rejecting patches.
- Integration (30%)
Applying new patches from the contributors while spotting and
correcting minor mistakes, shuffling the integration and
testing branches, pushing the results out, cutting the
releases, and making announcements.
- Own development (10%)
Scratching my own itch and sending proposed patch series out.
The policy on Integration is informally mentioned in "A Note
from the maintainer" message, which is periodically posted to
this mailing list after each feature release is made.
The policy.
- Feature releases are numbered as vX.Y.Z and are meant to
contain bugfixes and enhancements in any area, including
functionality, performance and usability, without regression.
- Maintenance releases are numbered as vX.Y.Z.W and are meant
to contain only bugfixes for the corresponding vX.Y.Z feature
release and earlier maintenance releases vX.Y.Z.V (V < W).
- 'master' branch is used to prepare for the next feature
release. In other words, at some point, the tip of 'master'
branch is tagged with vX.Y.Z.
- 'maint' branch is used to prepare for the next maintenance
release. After the feature release vX.Y.Z is made, the tip
of 'maint' branch is set to that release, and bugfixes will
accumulate on the branch, and at some point, the tip of the
branch is tagged with vX.Y.Z.1, vX.Y.Z.2, and so on.
- 'next' branch is used to publish changes (both enhancements
and fixes) that (1) have worthwhile goal, (2) are in a fairly
good shape suitable for everyday use, (3) but have not yet
demonstrated to be regression free. New changes are tested
in 'next' before merged to 'master'.
- 'pu' branch is used to publish other proposed changes that do
not yet pass the criteria set for 'next'.
- The tips of 'master', 'maint' and 'next' branches will always
fast forward, to allow people to build their own
customization on top of them.
- Usually 'master' contains all of 'maint', 'next' contains all
of 'master' and 'pu' contains all of 'next'.
- The tip of 'master' is meant to be more stable than any
tagged releases, and the users are encouraged to follow it.
- The 'next' branch is where new action takes place, and the
users are encouraged to test it so that regressions and bugs
are found before new topics are merged to 'master'.
A typical git day for the maintainer implements the above policy
by doing the following:
- Scan mailing list and #git channel log. Respond with review
comments, suggestions etc. Kibitz. Collect potentially
usable patches from the mailing list. Patches about a single
topic go to one mailbox (I read my mail in Gnus, and type
\C-o to save/append messages in files in mbox format).
- Review the patches in the saved mailboxes. Edit proposed log
message for typofixes and clarifications, and add Acks
collected from the list. Edit patch to incorporate "Oops,
that should have been like this" fixes from the discussion.
- Classify the collected patches and handle 'master' and
'maint' updates:
- Obviously correct fixes that pertain to the tip of 'maint'
are directly applied to 'maint'.
- Obviously correct fixes that pertain to the tip of 'master'
are directly applied to 'master'.
This step is done with "git am".
$ git checkout master ;# or "git checkout maint"
$ git am -3 -s mailbox
$ make test
- Merge downwards (maint->master):
$ git checkout master
$ git merge maint
$ make test
- Review the last issue of "What's cooking" message, review the
topics scheduled for merging upwards (topic->master and
topic->maint), and merge.
$ git checkout master ;# or "git checkout maint"
$ git merge ai/topic ;# or "git merge ai/maint-topic"
$ git log -p ORIG_HEAD.. ;# final review
$ git diff ORIG_HEAD.. ;# final review
$ make test ;# final review
$ git branch -d ai/topic ;# or "git branch -d ai/maint-topic"
- Merge downwards (maint->master) if needed:
$ git checkout master
$ git merge maint
$ make test
- Merge downwards (master->next) if needed:
$ git checkout next
$ git merge master
$ make test
- Handle the remaining patches:
- Anything unobvious that is applicable to 'master' (in other
words, does not depend on anything that is still in 'next'
and not in 'master') is applied to a new topic branch that
is forked from the tip of 'master'. This includes both
enhancements and unobvious fixes to 'master'. A topic
branch is named as ai/topic where "ai" is typically
author's initial and "topic" is a descriptive name of the
topic (in other words, "what's the series is about").
- An unobvious fix meant for 'maint' is applied to a new
topic branch that is forked from the tip of 'maint'. The
topic is named as ai/maint-topic.
- Changes that pertain to an existing topic are applied to
the branch, but:
- obviously correct ones are applied first;
- questionable ones are discarded or applied to near the tip;
- Replacement patches to an existing topic are accepted only
for commits not in 'next'.
The above except the "replacement" are all done with:
$ git am -3 -s mailbox
while patch replacement is often done by:
$ git format-patch ai/topic~$n..ai/topic ;# export existing
then replace some parts with the new patch, and reapplying:
$ git reset --hard ai/topic~$n
$ git am -3 -s 000*.txt
The full test suite is always run for 'maint' and 'master'
after patch application; for topic branches the tests are run
as time permits.
- Update "What's cooking" message to review the updates to
existing topics, newly added topics and graduated topics.
This step is helped with Meta/UWC script (where Meta/ contains
a checkout of the 'todo' branch).
- Merge topics to 'next'. For each branch whose tip is not
merged to 'next', one of three things can happen:
- The commits are all next-worthy; merge the topic to next:
$ git checkout next
$ git merge ai/topic ;# or "git merge ai/maint-topic"
$ make test
- The new parts are of mixed quality, but earlier ones are
next-worthy; merge the early parts to next:
$ git checkout next
$ git merge ai/topic~2 ;# the tip two are dubious
$ make test
- Nothing is next-worthy; do not do anything.
- Rebase topics that do not have any commit in next yet. This
step is optional but sometimes is worth doing when an old
series that is not in next can take advantage of low-level
framework change that is merged to 'master' already.
$ git rebase master ai/topic
This step is helped with Meta/git-topic.perl script to
identify which topic is rebaseable. There also is a
pre-rebase hook to make sure that topics that are already in
'next' are not rebased beyond the merged commit.
- Rebuild "pu" to merge the tips of topics not in 'next'.
$ git checkout pu
$ git reset --hard next
$ git merge ai/topic ;# repeat for all remaining topics
$ make test
This step is helped with Meta/PU script
- Push four integration branches to a private repository at
k.org and run "make test" on all of them.
- Push four integration branches to /pub/scm/git/git.git at
k.org. This triggers its post-update hook which:
(1) runs "git pull" in $HOME/git-doc/ repository to pull
'master' just pushed out;
(2) runs "make doc" in $HOME/git-doc/, install the generated
documentation in staging areas, which are separate
repositories that have html and man branches checked
out.
(3) runs "git commit" in the staging areas, and run "git
push" back to /pub/scm/git/git.git/ to update the html
and man branches.
(4) installs generated documentation to /pub/software/scm/git/docs/
to be viewed from http://www.kernel.org/
- Fetch html and man branches back from k.org, and push four
integration branches and the two documentation branches to
repo.or.cz
Some observations to be made.
* Each topic is tested individually, and also together with
other topics cooking in 'next'. Until it matures, none part
of it is merged to 'master'.
* A topic already in 'next' can get fixes while still in
'next'. Such a topic will have many merges to 'next' (in
other words, "git log --first-parent next" will show many
"Merge ai/topic to next" for the same topic.
* An unobvious fix for 'maint' is cooked in 'next' and then
merged to 'master' to make extra sure it is Ok and then
merged to 'maint'.
* Even when 'next' becomes empty (in other words, all topics
prove stable and are merged to 'master' and "git diff master
next" shows empty), it has tons of merge commits that will
never be in 'master'.
* In principle, "git log --first-parent master..next" should
show nothing but merges (in practice, there are fixup commits
and reverts that are not merges).
* Commits near the tip of a topic branch that are not in 'next'
are fair game to be discarded, replaced or rewritten.
Commits already merged to 'next' will not be.
* Being in the 'next' branch is not a guarantee for a topic to
be included in the next feature release. Being in the
'master' branch typically is.

View File

@@ -36,5 +36,11 @@ To sync with a local directory, you can use:
- file:///path/to/repo.git/
===============================================================
ifndef::git-clone[]
They are mostly equivalent, except when cloning. See
gitlink:git-clone[1] for details.
endif::git-clone[]
ifdef::git-clone[]
They are equivalent, except the former implies --local option.
endif::git-clone[]

View File

@@ -658,16 +658,23 @@ gitlink:git-diff[1]:
$ git diff master..test
-------------------------------------------------
Sometimes what you want instead is a set of patches:
That will produce the diff between the tips of the two branches. If
you'd prefer to find the diff from their common ancestor to test, you
can use three dots instead of two:
-------------------------------------------------
$ git diff master...test
-------------------------------------------------
Sometimes what you want instead is a set of patches; for this you can
use gitlink:git-format-patch[1]:
-------------------------------------------------
$ git format-patch master..test
-------------------------------------------------
will generate a file with a patch for each commit reachable from test
but not from master. Note that if master also has commits which are
not reachable from test, then the combined result of these patches
will not be the same as the diff produced by the git-diff example.
but not from master.
[[viewing-old-file-versions]]
Viewing old file versions
@@ -1567,9 +1574,9 @@ old history using, for example,
$ git log master@{1}
-------------------------------------------------
This lists the commits reachable from the previous version of the head.
This syntax can be used with any git command that accepts a commit,
not just with git log. Some other examples:
This lists the commits reachable from the previous version of the
"master" branch head. This syntax can be used with any git command
that accepts a commit, not just with git log. Some other examples:
-------------------------------------------------
$ git show master@{2} # See where the branch pointed 2,
@@ -2554,6 +2561,72 @@ branches into their own work.
For true distributed development that supports proper merging,
published branches should never be rewritten.
[[bisect-merges]]
Why bisecting merge commits can be harder than bisecting linear history
-----------------------------------------------------------------------
The gitlink:git-bisect[1] command correctly handles history that
includes merge commits. However, when the commit that it finds is a
merge commit, the user may need to work harder than usual to figure out
why that commit introduced a problem.
Imagine this history:
................................................
---Z---o---X---...---o---A---C---D
\ /
o---o---Y---...---o---B
................................................
Suppose that on the upper line of development, the meaning of one
of the functions that exists at Z is changed at commit X. The
commits from Z leading to A change both the function's
implementation and all calling sites that exist at Z, as well
as new calling sites they add, to be consistent. There is no
bug at A.
Suppose that in the meantime on the lower line of development somebody
adds a new calling site for that function at commit Y. The
commits from Z leading to B all assume the old semantics of that
function and the callers and the callee are consistent with each
other. There is no bug at B, either.
Suppose further that the two development lines merge cleanly at C,
so no conflict resolution is required.
Nevertheless, the code at C is broken, because the callers added
on the lower line of development have not been converted to the new
semantics introduced on the upper line of development. So if all
you know is that D is bad, that Z is good, and that
gitlink:git-bisect[1] identifies C as the culprit, how will you
figure out that the problem is due to this change in semantics?
When the result of a git-bisect is a non-merge commit, you should
normally be able to discover the problem by examining just that commit.
Developers can make this easy by breaking their changes into small
self-contained commits. That won't help in the case above, however,
because the problem isn't obvious from examination of any single
commit; instead, a global view of the development is required. To
make matters worse, the change in semantics in the problematic
function may be just one small part of the changes in the upper
line of development.
On the other hand, if instead of merging at C you had rebased the
history between Z to B on top of A, you would have gotten this
linear history:
................................................................
---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D*
................................................................
Bisecting between Z and D* would hit a single culprit commit Y*,
and understanding why Y* was broken would probably be easier.
Partly for this reason, many experienced git users, even when
working on an otherwise merge-heavy project, keep the history
linear by rebasing against the latest upstream version before
publishing.
[[advanced-branch-management]]
Advanced branch management
==========================

View File

@@ -224,7 +224,7 @@ SCRIPT_SH = \
git-sh-setup.sh \
git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh \
git-merge-resolve.sh \
git-lost-found.sh git-quiltimport.sh git-submodule.sh \
git-filter-branch.sh \
git-stash.sh
@@ -355,6 +355,7 @@ BUILTIN_OBJS = \
builtin-mailsplit.o \
builtin-merge-base.o \
builtin-merge-file.o \
builtin-merge-ours.o \
builtin-mv.o \
builtin-name-rev.o \
builtin-pack-objects.o \
@@ -418,18 +419,17 @@ ifeq ($(uname_S),SunOS)
NO_STRCASESTR = YesPlease
NO_MEMMEM = YesPlease
NO_HSTRERROR = YesPlease
NO_MKDTEMP = YesPlease
ifeq ($(uname_R),5.8)
NEEDS_LIBICONV = YesPlease
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
NO_MKDTEMP = YesPlease
NO_C99_FORMAT = YesPlease
NO_STRTOUMAX = YesPlease
endif
ifeq ($(uname_R),5.9)
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
NO_MKDTEMP = YesPlease
NO_C99_FORMAT = YesPlease
NO_STRTOUMAX = YesPlease
endif

View File

@@ -683,7 +683,6 @@ static char *git_header_name(char *line, int llen)
}
}
}
return NULL;
}
/* Verify that we recognize the lines following a git header */

View File

@@ -335,7 +335,7 @@ static struct origin *find_origin(struct scoreboard *sb,
* same and diff-tree is fairly efficient about this.
*/
diff_setup(&diff_opts);
diff_opts.recursive = 1;
DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = 0;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
paths[0] = origin->path;
@@ -409,7 +409,7 @@ static struct origin *find_rename(struct scoreboard *sb,
const char *paths[2];
diff_setup(&diff_opts);
diff_opts.recursive = 1;
DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin->path;
@@ -1075,7 +1075,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
return 1; /* nothing remains for this target */
diff_setup(&diff_opts);
diff_opts.recursive = 1;
DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
paths[0] = NULL;
@@ -1093,7 +1093,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
if ((opt & PICKAXE_BLAME_COPY_HARDEST)
|| ((opt & PICKAXE_BLAME_COPY_HARDER)
&& (!porigin || strcmp(target->path, porigin->path))))
diff_opts.find_copies_harder = 1;
DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
if (is_null_sha1(target->commit->object.sha1))
do_diff_cache(parent->tree->object.sha1, &diff_opts);
@@ -1102,7 +1102,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
target->commit->tree->object.sha1,
"", &diff_opts);
if (!diff_opts.find_copies_harder)
if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER))
diffcore_std(&diff_opts);
retval = 0;

View File

@@ -507,48 +507,36 @@ static void rename_branch(const char *oldname, const char *newname, int force)
int cmd_branch(int argc, const char **argv, const char *prefix)
{
int delete = 0, force_delete = 0, force_create = 0;
int rename = 0, force_rename = 0;
int delete = 0, rename = 0, force_create = 0;
int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
int reflog = 0, track;
int kinds = REF_LOCAL_BRANCH, kind_remote = 0, kind_any = 0;
int kinds = REF_LOCAL_BRANCH;
struct option options[] = {
OPT_GROUP("Generic options"),
OPT__VERBOSE(&verbose),
OPT_BOOLEAN( 0 , "track", &track, "set up tracking mode (see git-pull(1))"),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
OPT_BOOLEAN('r', NULL, &kind_remote, "act on remote-tracking branches"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
OPT__ABBREV(&abbrev),
OPT_GROUP("Specific git-branch actions:"),
OPT_BOOLEAN('a', NULL, &kind_any, "list both remote-tracking and local branches"),
OPT_BOOLEAN('d', NULL, &delete, "delete fully merged branch"),
OPT_BOOLEAN('D', NULL, &force_delete, "delete branch (even if not merged)"),
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
OPT_BOOLEAN('m', NULL, &rename, "move/rename a branch and its reflog"),
OPT_BOOLEAN('M', NULL, &force_rename, "move/rename a branch, even if target exists"),
OPT_SET_INT('a', NULL, &kinds, "list both remote-tracking and local branches",
REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
OPT_BIT('d', NULL, &delete, "delete fully merged branch", 1),
OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2),
OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
OPT_END(),
};
git_config(git_branch_config);
track = branch_track;
argc = parse_options(argc, argv, options, builtin_branch_usage, 0);
delete |= force_delete;
rename |= force_rename;
if (kind_remote)
kinds = REF_REMOTE_BRANCH;
if (kind_any)
kinds = REF_REMOTE_BRANCH | REF_LOCAL_BRANCH;
if (abbrev && abbrev < MINIMUM_ABBREV)
abbrev = MINIMUM_ABBREV;
else if (abbrev > 40)
abbrev = 40;
if ((delete && rename) || (delete && force_create) ||
(rename && force_create))
if (!!delete + !!rename + !!force_create > 1)
usage_with_options(builtin_branch_usage, options);
head = resolve_ref("HEAD", head_sha1, 0, NULL);
@@ -564,13 +552,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
}
if (delete)
return delete_branches(argc, argv, force_delete, kinds);
return delete_branches(argc, argv, delete > 1, kinds);
else if (argc == 0)
print_ref_list(kinds, detached, verbose, abbrev);
else if (rename && (argc == 1))
rename_branch(head, argv[0], force_rename);
rename_branch(head, argv[0], rename > 1);
else if (rename && (argc == 2))
rename_branch(argv[0], argv[1], force_rename);
rename_branch(argv[0], argv[1], rename > 1);
else if (argc <= 2)
create_branch(argv[0], (argc == 2) ? argv[1] : head,
force_create, reflog, track);

View File

@@ -31,5 +31,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
result = run_diff_files_cmd(&rev, argc, argv);
return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
return result;
}

View File

@@ -44,5 +44,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
return -1;
}
result = run_diff_index(&rev, cached);
return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
return result;
}

View File

@@ -118,8 +118,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
}
if (!read_stdin)
return opt->diffopt.exit_with_status ?
opt->diffopt.has_changes: 0;
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
@@ -134,5 +134,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
else
diff_tree_stdin(line);
}
return opt->diffopt.exit_with_status ? opt->diffopt.has_changes: 0;
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
}

View File

@@ -35,7 +35,7 @@ static void stuff_change(struct diff_options *opt,
!hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
return;
if (opt->reverse_diff) {
if (DIFF_OPT_TST(opt, REVERSE_DIFF)) {
unsigned tmp;
const unsigned char *tmp_u;
const char *tmp_c;
@@ -253,13 +253,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (diff_setup_done(&rev.diffopt) < 0)
die("diff_setup_done failed");
}
rev.diffopt.allow_external = 1;
rev.diffopt.recursive = 1;
DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
/* If the user asked for our exit code then don't start a
* pager or we would end up reporting its exit code instead.
*/
if (!rev.diffopt.exit_with_status)
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
setup_pager();
/* Do we have --cached and not have a pending object, then
@@ -363,8 +363,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
else
result = builtin_diff_combined(&rev, argc, argv,
ent, ents);
if (rev.diffopt.exit_with_status)
result = rev.diffopt.has_changes;
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
if (1 < rev.diffopt.skip_stat_unmatch)
refresh_index_quietly();

View File

@@ -178,7 +178,7 @@ static void shortlog(const char *name, unsigned char *sha1,
struct commit *commit;
struct object *branch;
struct list subjects = { NULL, NULL, 0, 0 };
int flags = UNINTERESTING | TREECHANGE | SEEN | SHOWN | ADDED;
int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
if (!branch || branch->type != OBJ_COMMIT)

View File

@@ -833,16 +833,19 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
int i, num_refs;
const char *format = "%(objectname) %(objecttype)\t%(refname)";
struct ref_sort *sort = NULL, **sort_tail = &sort;
int maxcount = 0, quote_style;
int quote_shell = 0, quote_perl = 0, quote_python = 0, quote_tcl = 0;
int maxcount = 0, quote_style = 0;
struct refinfo **refs;
struct grab_ref_cbdata cbdata;
struct option opts[] = {
OPT_BOOLEAN('s', "shell", &quote_shell, "quote placeholders suitably for shells"),
OPT_BOOLEAN('p', "perl", &quote_perl, "quote placeholders suitably for perl"),
OPT_BOOLEAN( 0 , "python", &quote_python, "quote placeholders suitably for python"),
OPT_BOOLEAN( 0 , "tcl", &quote_tcl, "quote placeholders suitably for tcl"),
OPT_BIT('s', "shell", &quote_style,
"quote placeholders suitably for shells", QUOTE_SHELL),
OPT_BIT('p', "perl", &quote_style,
"quote placeholders suitably for perl", QUOTE_PERL),
OPT_BIT(0 , "python", &quote_style,
"quote placeholders suitably for python", QUOTE_PYTHON),
OPT_BIT(0 , "tcl", &quote_style,
"quote placeholders suitably for tcl", QUOTE_TCL),
OPT_GROUP(""),
OPT_INTEGER( 0 , "count", &maxcount, "show only <n> matched refs"),
@@ -857,15 +860,13 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
error("invalid --count argument: `%d'", maxcount);
usage_with_options(for_each_ref_usage, opts);
}
if (quote_shell + quote_perl + quote_python + quote_tcl > 1) {
if (HAS_MULTI_BITS(quote_style)) {
error("more than one quoting style ?");
usage_with_options(for_each_ref_usage, opts);
}
if (verify_format(format))
usage_with_options(for_each_ref_usage, opts);
quote_style = QUOTE_SHELL * quote_shell + QUOTE_PERL * quote_perl +
QUOTE_PYTHON * quote_python + QUOTE_TCL * quote_tcl;
if (!sort)
sort = default_sort();
sort_atom_limit = used_atom_cnt;

View File

@@ -294,7 +294,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
if (opt->pre_context) {
push_arg("-B");
len += snprintf(argptr, sizeof(randarg)-len,
"%u", opt->pre_context);
"%u", opt->pre_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);
@@ -303,7 +303,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
if (opt->post_context) {
push_arg("-A");
len += snprintf(argptr, sizeof(randarg)-len,
"%u", opt->post_context);
"%u", opt->post_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);
@@ -313,7 +313,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
else {
push_arg("-C");
len += snprintf(argptr, sizeof(randarg)-len,
"%u", opt->post_context);
"%u", opt->post_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);

View File

@@ -55,13 +55,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
rev->verbose_header = 1;
rev->diffopt.recursive = 1;
DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
argc = setup_revisions(argc, argv, rev, "HEAD");
if (rev->diffopt.pickaxe || rev->diffopt.filter)
rev->always_show_header = 0;
if (rev->diffopt.follow_renames) {
if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
rev->always_show_header = 0;
if (rev->diffopt.nr_paths != 1)
usage("git logs can only follow renames on one pathname at a time");
@@ -77,11 +77,134 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
}
}
/*
* This gives a rough estimate for how many commits we
* will print out in the list.
*/
static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
{
int n = 0;
while (list) {
struct commit *commit = list->item;
unsigned int flags = commit->object.flags;
list = list->next;
if (!(flags & (TREESAME | UNINTERESTING)))
n++;
}
return n;
}
static void show_early_header(struct rev_info *rev, const char *stage, int nr)
{
if (rev->shown_one) {
rev->shown_one = 0;
if (rev->commit_format != CMIT_FMT_ONELINE)
putchar(rev->diffopt.line_termination);
}
printf("Final output: %d %s\n", nr, stage);
}
struct itimerval early_output_timer;
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
int i = revs->early_output;
int show_header = 1;
sort_in_topological_order(&list, revs->lifo);
while (list && i) {
struct commit *commit = list->item;
switch (simplify_commit(revs, commit)) {
case commit_show:
if (show_header) {
int n = estimate_commit_count(revs, list);
show_early_header(revs, "incomplete", n);
show_header = 0;
}
log_tree_commit(revs, commit);
i--;
break;
case commit_ignore:
break;
case commit_error:
return;
}
list = list->next;
}
/* Did we already get enough commits for the early output? */
if (!i)
return;
/*
* ..if no, then repeat it twice a second until we
* do.
*
* NOTE! We don't use "it_interval", because if the
* reader isn't listening, we want our output to be
* throttled by the writing, and not have the timer
* trigger every second even if we're blocked on a
* reader!
*/
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 500000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
}
static void early_output(int signal)
{
show_early_output = log_show_early;
}
static void setup_early_output(struct rev_info *rev)
{
struct sigaction sa;
/*
* Set up the signal handler, minimally intrusively:
* we only set a single volatile integer word (not
* using sigatomic_t - trying to avoid unnecessary
* system dependencies and headers), and using
* SA_RESTART.
*/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = early_output;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGALRM, &sa, NULL);
/*
* If we can get the whole output in less than a
* tenth of a second, don't even bother doing the
* early-output thing..
*
* This is a one-time-only trigger.
*/
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 100000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
}
static void finish_early_output(struct rev_info *rev)
{
int n = estimate_commit_count(rev, rev->commits);
signal(SIGALRM, SIG_IGN);
show_early_header(rev, "done", n);
}
static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;
if (rev->early_output)
setup_early_output(rev);
prepare_revision_walk(rev);
if (rev->early_output)
finish_early_output(rev);
while ((commit = get_revision(rev)) != NULL) {
log_tree_commit(rev, commit);
if (!rev->reflog_info) {
@@ -185,11 +308,9 @@ int cmd_show(int argc, const char **argv, const char *prefix)
struct tag *t = (struct tag *)o;
printf("%stag %s%s\n\n",
diff_get_color(rev.diffopt.color_diff,
DIFF_COMMIT),
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
t->tag,
diff_get_color(rev.diffopt.color_diff,
DIFF_RESET));
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
ret = show_object(o->sha1, 1);
objects[i].item = (struct object *)t->tagged;
i--;
@@ -197,11 +318,9 @@ int cmd_show(int argc, const char **argv, const char *prefix)
}
case OBJ_TREE:
printf("%stree %s%s\n\n",
diff_get_color(rev.diffopt.color_diff,
DIFF_COMMIT),
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
name,
diff_get_color(rev.diffopt.color_diff,
DIFF_RESET));
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
show_tree_object);
break;
@@ -497,7 +616,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.combine_merges = 0;
rev.ignore_merges = 1;
rev.diffopt.msg_sep = "";
rev.diffopt.recursive = 1;
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
rev.subject_prefix = fmt_patch_subject_prefix;
rev.extra_headers = extra_headers;
@@ -605,8 +724,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
if (!rev.diffopt.text)
rev.diffopt.binary = 1;
if (!DIFF_OPT_TST(&rev.diffopt, TEXT))
DIFF_OPT_SET(&rev.diffopt, BINARY);
if (!output_directory && !use_stdout)
output_directory = prefix;
@@ -764,7 +883,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
revs.diff = 1;
revs.combine_merges = 0;
revs.ignore_merges = 1;
revs.diffopt.recursive = 1;
DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
if (add_pending_commit(head, &revs, 0))
die("Unknown commit %s", head);

View File

@@ -387,8 +387,8 @@ static void overlay_tree(const char *tree_name, const char *prefix)
static const char ls_files_usage[] =
"git-ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
"[--] [<file>]*";
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
"[--full-name] [--abbrev] [--] [<file>]*";
int cmd_ls_files(int argc, const char **argv, const char *prefix)
{
@@ -496,6 +496,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
dir.exclude_per_dir = arg + 24;
continue;
}
if (!strcmp(arg, "--exclude-standard")) {
exc_given = 1;
setup_standard_excludes(&dir);
continue;
}
if (!strcmp(arg, "--full-name")) {
prefix_offset = 0;
continue;

28
builtin-merge-ours.c Normal file
View File

@@ -0,0 +1,28 @@
/*
* Implementation of git-merge-ours.sh as builtin
*
* Copyright (c) 2007 Thomas Harning Jr
* Original:
* Original Copyright (c) 2005 Junio C Hamano
*
* Pretend we resolved the heads, but declare our tree trumps everybody else.
*/
#include "git-compat-util.h"
#include "builtin.h"
static const char *diff_index_args[] = {
"diff-index", "--quiet", "--cached", "HEAD", "--", NULL
};
#define NARGS (ARRAY_SIZE(diff_index_args) - 1)
int cmd_merge_ours(int argc, const char **argv, const char *prefix)
{
/*
* We need to exit with 2 if the index does not match our HEAD tree,
* because the current index is what we will be committing as the
* merge result.
*/
if (cmd_diff_index(NARGS, diff_index_args, prefix))
exit(2);
exit(0);
}

View File

@@ -990,7 +990,7 @@ static void add_pbase_object(struct tree_desc *tree,
return;
if (name[cmplen] != '/') {
add_object_entry(entry.sha1,
S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB,
object_type(entry.mode),
fullname, 1);
return;
}

View File

@@ -122,19 +122,13 @@ static char const * const pack_refs_usage[] = {
int cmd_pack_refs(int argc, const char **argv, const char *prefix)
{
int all = 0, prune = 1;
unsigned int flags = 0;
unsigned int flags = PACK_REFS_PRUNE;
struct option opts[] = {
OPT_BOOLEAN(0, "all", &all, "pack everything"),
OPT_BOOLEAN(0, "prune", &prune, "prune loose refs (default)"),
OPT_BIT(0, "all", &flags, "pack everything", PACK_REFS_ALL),
OPT_BIT(0, "prune", &flags, "prune loose refs (default)", PACK_REFS_PRUNE),
OPT_END(),
};
if (parse_options(argc, argv, opts, pack_refs_usage, 0))
usage_with_options(pack_refs_usage, opts);
if (prune)
flags |= PACK_REFS_PRUNE;
if (all)
flags |= PACK_REFS_ALL;
return pack_refs(flags);
}

View File

@@ -153,7 +153,7 @@ static int count_distance(struct commit_list *entry)
if (commit->object.flags & (UNINTERESTING | COUNTED))
break;
if (!revs.prune_fn || (commit->object.flags & TREECHANGE))
if (!(commit->object.flags & TREESAME))
nr++;
commit->object.flags |= COUNTED;
p = commit->parents;
@@ -209,7 +209,7 @@ static inline int halfway(struct commit_list *p, int nr)
/*
* Don't short-cut something we are not going to return!
*/
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
if (p->item->object.flags & TREESAME)
return 0;
if (DEBUG_BISECT)
return 0;
@@ -245,7 +245,7 @@ static void show_list(const char *debug, int counted, int nr,
char *ep, *sp;
fprintf(stderr, "%c%c%c ",
(flags & TREECHANGE) ? 'T' : ' ',
(flags & TREESAME) ? ' ' : 'T',
(flags & UNINTERESTING) ? 'U' : ' ',
(flags & COUNTED) ? 'C' : ' ');
if (commit->util)
@@ -279,7 +279,7 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
int distance;
unsigned flags = p->item->object.flags;
if (revs.prune_fn && !(flags & TREECHANGE))
if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
@@ -319,7 +319,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
int distance;
unsigned flags = p->item->object.flags;
if (revs.prune_fn && !(flags & TREECHANGE))
if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
@@ -373,7 +373,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
p->item->util = &weights[n++];
switch (count_interesting_parents(commit)) {
case 0:
if (!revs.prune_fn || (flags & TREECHANGE)) {
if (!(flags & TREESAME)) {
weight_set(p, 1);
counted++;
show_list("bisection 2 count one",
@@ -446,7 +446,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
* add one for p itself if p is to be counted,
* otherwise inherit it from q directly.
*/
if (!revs.prune_fn || (flags & TREECHANGE)) {
if (!(flags & TREESAME)) {
weight_set(p, weight(q)+1);
counted++;
show_list("bisection 2 count one",
@@ -493,7 +493,7 @@ static struct commit_list *find_bisection(struct commit_list *list,
continue;
p->next = last;
last = p;
if (!revs.prune_fn || (flags & TREECHANGE))
if (!(flags & TREESAME))
nr++;
on_list++;
}

View File

@@ -8,6 +8,7 @@
#include "refs.h"
#include "quote.h"
#include "builtin.h"
#include "parse-options.h"
#define DO_REVS 1
#define DO_NOREV 2
@@ -209,13 +210,138 @@ static int try_difference(const char *arg)
return 0;
}
static int parseopt_dump(const struct option *o, const char *arg, int unset)
{
struct strbuf *parsed = o->value;
if (unset)
strbuf_addf(parsed, " --no-%s", o->long_name);
else if (o->short_name)
strbuf_addf(parsed, " -%c", o->short_name);
else
strbuf_addf(parsed, " --%s", o->long_name);
if (arg) {
strbuf_addch(parsed, ' ');
sq_quote_buf(parsed, arg);
}
return 0;
}
static const char *skipspaces(const char *s)
{
while (isspace(*s))
s++;
return s;
}
static int cmd_parseopt(int argc, const char **argv, const char *prefix)
{
static int keep_dashdash = 0;
static char const * const parseopt_usage[] = {
"git-rev-parse --parseopt [options] -- [<args>...]",
NULL
};
static struct option parseopt_opts[] = {
OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
"keep the `--` passed as an arg"),
OPT_END(),
};
struct strbuf sb, parsed;
const char **usage = NULL;
struct option *opts = NULL;
int onb = 0, osz = 0, unb = 0, usz = 0;
strbuf_init(&parsed, 0);
strbuf_addstr(&parsed, "set --");
argc = parse_options(argc, argv, parseopt_opts, parseopt_usage,
PARSE_OPT_KEEP_DASHDASH);
if (argc < 1 || strcmp(argv[0], "--"))
usage_with_options(parseopt_usage, parseopt_opts);
strbuf_init(&sb, 0);
/* get the usage up to the first line with a -- on it */
for (;;) {
if (strbuf_getline(&sb, stdin, '\n') == EOF)
die("premature end of input");
ALLOC_GROW(usage, unb + 1, usz);
if (!strcmp("--", sb.buf)) {
if (unb < 1)
die("no usage string given before the `--' separator");
usage[unb] = NULL;
break;
}
usage[unb++] = strbuf_detach(&sb, NULL);
}
/* parse: (<short>|<short>,<long>|<long>)[=?]? SP+ <help> */
while (strbuf_getline(&sb, stdin, '\n') != EOF) {
const char *s;
struct option *o;
if (!sb.len)
continue;
ALLOC_GROW(opts, onb + 1, osz);
memset(opts + onb, 0, sizeof(opts[onb]));
o = &opts[onb++];
s = strchr(sb.buf, ' ');
if (!s || *sb.buf == ' ') {
o->type = OPTION_GROUP;
o->help = xstrdup(skipspaces(s));
continue;
}
o->type = OPTION_CALLBACK;
o->help = xstrdup(skipspaces(s));
o->value = &parsed;
o->callback = &parseopt_dump;
switch (s[-1]) {
case '=':
s--;
break;
case '?':
o->flags = PARSE_OPT_OPTARG;
s--;
break;
default:
o->flags = PARSE_OPT_NOARG;
break;
}
if (s - sb.buf == 1) /* short option only */
o->short_name = *sb.buf;
else if (sb.buf[1] != ',') /* long option only */
o->long_name = xmemdupz(sb.buf, s - sb.buf);
else {
o->short_name = *sb.buf;
o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
}
}
strbuf_release(&sb);
/* put an OPT_END() */
ALLOC_GROW(opts, onb + 1, osz);
memset(opts + onb, 0, sizeof(opts[onb]));
argc = parse_options(argc, argv, opts, usage,
keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0);
strbuf_addf(&parsed, " --");
sq_quote_argv(&parsed, argv, argc, 0);
puts(parsed.buf);
return 0;
}
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0;
unsigned char sha1[20];
git_config(git_default_config);
if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
prefix = setup_git_directory();
git_config(git_default_config);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];

View File

@@ -51,6 +51,7 @@ extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
extern int cmd_merge_base(int argc, const char **argv, const char *prefix);
extern int cmd_merge_ours(int argc, const char **argv, const char *prefix);
extern int cmd_merge_file(int argc, const char **argv, const char *prefix);
extern int cmd_mv(int argc, const char **argv, const char *prefix);
extern int cmd_name_rev(int argc, const char **argv, const char *prefix);

View File

@@ -6,6 +6,7 @@
#include "revision.h"
#include "list-objects.h"
#include "run-command.h"
#include "refs.h"
static const char bundle_signature[] = "# v2 git bundle\n";
@@ -232,11 +233,17 @@ int create_bundle(struct bundle_header *header, const char *path,
struct object_array_entry *e = revs.pending.objects + i;
unsigned char sha1[20];
char *ref;
const char *display_ref;
int flag;
if (e->item->flags & UNINTERESTING)
continue;
if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1)
continue;
if (!resolve_ref(e->name, sha1, 1, &flag))
flag = 0;
display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
/*
* Make sure the refs we wrote out is correct; --max-count and
* other limiting options could have prevented all the tips
@@ -287,7 +294,7 @@ int create_bundle(struct bundle_header *header, const char *path,
ref_count++;
write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40);
write_or_die(bundle_fd, " ", 1);
write_or_die(bundle_fd, ref, strlen(ref));
write_or_die(bundle_fd, display_ref, strlen(display_ref));
write_or_die(bundle_fd, "\n", 1);
free(ref);
}

View File

@@ -664,7 +664,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int mode_differs = 0;
int i, show_hunks;
int working_tree_file = is_null_sha1(elem->sha1);
int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV;
int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
mmfile_t result_file;
context = opt->context;
@@ -784,7 +784,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (show_hunks || mode_differs || working_tree_file) {
const char *abb;
int use_color = opt->color_diff;
int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
int added = 0;
@@ -836,7 +836,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
dump_quoted_path("+++ /dev/", "null", c_meta, c_reset);
else
dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
dump_sline(sline, cnt, num_parent, opt->color_diff);
dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF));
}
free(result);
@@ -929,8 +929,8 @@ void diff_tree_combined(const unsigned char *sha1,
diffopts = *opt;
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diffopts.recursive = 1;
diffopts.allow_external = 0;
DIFF_OPT_SET(&diffopts, RECURSIVE);
DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
show_log_first = !!rev->loginfo && !rev->no_commit_id;
needsep = 0;

148
commit.c
View File

@@ -8,22 +8,6 @@
int save_commit_buffer = 1;
struct sort_node
{
/*
* the number of children of the associated commit
* that also occur in the list being sorted.
*/
unsigned int indegree;
/*
* reference to original list item that we will re-use
* on output.
*/
struct commit_list * list_item;
};
const char *commit_type = "commit";
static struct commit *check_commit(struct object *obj,
@@ -431,69 +415,38 @@ struct commit *pop_commit(struct commit_list **stack)
return item;
}
void topo_sort_default_setter(struct commit *c, void *data)
{
c->util = data;
}
void *topo_sort_default_getter(struct commit *c)
{
return c->util;
}
/*
* Performs an in-place topological sort on the list supplied.
*/
void sort_in_topological_order(struct commit_list ** list, int lifo)
{
sort_in_topological_order_fn(list, lifo, topo_sort_default_setter,
topo_sort_default_getter);
}
struct commit_list *next, *orig = *list;
struct commit_list *work, **insert;
struct commit_list **pptr;
void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
topo_sort_set_fn_t setter,
topo_sort_get_fn_t getter)
{
struct commit_list * next = *list;
struct commit_list * work = NULL, **insert;
struct commit_list ** pptr = list;
struct sort_node * nodes;
struct sort_node * next_nodes;
int count = 0;
/* determine the size of the list */
while (next) {
next = next->next;
count++;
}
if (!count)
if (!orig)
return;
/* allocate an array to help sort the list */
nodes = xcalloc(count, sizeof(*nodes));
/* link the list to the array */
next_nodes = nodes;
next=*list;
while (next) {
next_nodes->list_item = next;
setter(next->item, next_nodes);
next_nodes++;
next = next->next;
*list = NULL;
/* Mark them and clear the indegree */
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
commit->object.flags |= TOPOSORT;
commit->indegree = 0;
}
/* update the indegree */
next=*list;
while (next) {
for (next = orig; next; next = next->next) {
struct commit_list * parents = next->item->parents;
while (parents) {
struct commit * parent=parents->item;
struct sort_node * pn = (struct sort_node *) getter(parent);
struct commit *parent = parents->item;
if (pn)
pn->indegree++;
parents=parents->next;
if (parent->object.flags & TOPOSORT)
parent->indegree++;
parents = parents->next;
}
next=next->next;
}
/*
* find the tips
*
@@ -501,55 +454,56 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
*
* the tips serve as a starting set for the work queue.
*/
next=*list;
work = NULL;
insert = &work;
while (next) {
struct sort_node * node = (struct sort_node *) getter(next->item);
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
if (node->indegree == 0) {
insert = &commit_list_insert(next->item, insert)->next;
}
next=next->next;
if (!commit->indegree)
insert = &commit_list_insert(commit, insert)->next;
}
/* process the list in topological order */
if (!lifo)
sort_by_date(&work);
pptr = list;
*list = NULL;
while (work) {
struct commit * work_item = pop_commit(&work);
struct sort_node * work_node = (struct sort_node *) getter(work_item);
struct commit_list * parents = work_item->parents;
struct commit *commit;
struct commit_list *parents, *work_item;
while (parents) {
struct commit * parent=parents->item;
struct sort_node * pn = (struct sort_node *) getter(parent);
work_item = work;
work = work_item->next;
work_item->next = NULL;
if (pn) {
/*
* parents are only enqueued for emission
* when all their children have been emitted thereby
* guaranteeing topological order.
*/
pn->indegree--;
if (!pn->indegree) {
if (!lifo)
insert_by_date(parent, &work);
else
commit_list_insert(parent, &work);
}
commit = work_item->item;
for (parents = commit->parents; parents ; parents = parents->next) {
struct commit *parent=parents->item;
if (!(parent->object.flags & TOPOSORT))
continue;
/*
* parents are only enqueued for emission
* when all their children have been emitted thereby
* guaranteeing topological order.
*/
if (!--parent->indegree) {
if (!lifo)
insert_by_date(parent, &work);
else
commit_list_insert(parent, &work);
}
parents=parents->next;
}
/*
* work_item is a commit all of whose children
* have already been emitted. we can emit it now.
*/
*pptr = work_node->list_item;
pptr = &(*pptr)->next;
*pptr = NULL;
setter(work_item, NULL);
commit->object.flags &= ~TOPOSORT;
*pptr = work_item;
pptr = &work_item->next;
}
free(nodes);
}
/* merge-base stuff */

View File

@@ -14,6 +14,7 @@ struct commit_list {
struct commit {
struct object object;
void *util;
unsigned int indegree;
unsigned long date;
struct commit_list *parents;
struct tree *tree;
@@ -84,31 +85,12 @@ void clear_commit_marks(struct commit *commit, unsigned int mark);
/*
* Performs an in-place topological sort of list supplied.
*
* Pre-conditions for sort_in_topological_order:
* all commits in input list and all parents of those
* commits must have object.util == NULL
*
* Pre-conditions for sort_in_topological_order_fn:
* all commits in input list and all parents of those
* commits must have getter(commit) == NULL
*
* Post-conditions:
* invariant of resulting list is:
* a reachable from b => ord(b) < ord(a)
* in addition, when lifo == 0, commits on parallel tracks are
* sorted in the dates order.
*/
typedef void (*topo_sort_set_fn_t)(struct commit*, void *data);
typedef void* (*topo_sort_get_fn_t)(struct commit*);
void topo_sort_default_setter(struct commit *c, void *data);
void *topo_sort_default_getter(struct commit *c);
void sort_in_topological_order(struct commit_list ** list, int lifo);
void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
topo_sort_set_fn_t setter,
topo_sort_get_fn_t getter);
struct commit_graft {
unsigned char sha1[20];
@@ -135,4 +117,9 @@ extern int interactive_add(void);
extern void add_files_to_cache(int verbose, const char *prefix, const char **files);
extern int rerere(void);
static inline int single_parent(struct commit *commit)
{
return commit->parents && !commit->parents->next;
}
#endif /* COMMIT_H */

View File

@@ -35,7 +35,10 @@ NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@
NO_IPV6=@NO_IPV6@
NO_C99_FORMAT=@NO_C99_FORMAT@
NO_STRCASESTR=@NO_STRCASESTR@
NO_MEMMEM=@NO_MEMMEM@
NO_STRLCPY=@NO_STRLCPY@
NO_STRTOUMAX=@NO_STRTOUMAX@
NO_SETENV=@NO_SETENV@
NO_MKDTEMP=@NO_MKDTEMP@
NO_ICONV=@NO_ICONV@
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@

View File

@@ -289,18 +289,36 @@ AC_CHECK_FUNC(strcasestr,
[NO_STRCASESTR=YesPlease])
AC_SUBST(NO_STRCASESTR)
#
# Define NO_MEMMEM if you don't have memmem.
AC_CHECK_FUNC(memmem,
[NO_MEMMEM=],
[NO_MEMMEM=YesPlease])
AC_SUBST(NO_MEMMEM)
#
# Define NO_STRLCPY if you don't have strlcpy.
AC_CHECK_FUNC(strlcpy,
[NO_STRLCPY=],
[NO_STRLCPY=YesPlease])
AC_SUBST(NO_STRLCPY)
#
# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
AC_CHECK_FUNC(strtoumax,
[NO_STRTOUMAX=],
[NO_STRTOUMAX=YesPlease])
AC_SUBST(NO_STRTOUMAX)
#
# Define NO_SETENV if you don't have setenv in the C library.
AC_CHECK_FUNC(setenv,
[NO_SETENV=],
[NO_SETENV=YesPlease])
AC_SUBST(NO_SETENV)
#
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
AC_CHECK_FUNC(mkdtemp,
[NO_MKDTEMP=],
[NO_MKDTEMP=YesPlease])
AC_SUBST(NO_MKDTEMP)
#
# Define NO_MMAP if you want to avoid mmap.
#
# Define NO_ICONV if your libc does not properly support iconv.

View File

@@ -1141,7 +1141,7 @@ class P4Sync(Command):
l = p4CmdList("labels %s..." % ' '.join (self.depotPaths))
if len(l) > 0 and not self.silent:
print "Finding files belonging to labels in %s" % `self.depotPath`
print "Finding files belonging to labels in %s" % `self.depotPaths`
for output in l:
label = output["label"]
@@ -1207,6 +1207,15 @@ class P4Sync(Command):
for branch in lostAndFoundBranches:
self.knownBranches[branch] = branch
def getBranchMappingFromGitBranches(self):
branches = p4BranchesInGit(self.importIntoRemotes)
for branch in branches.keys():
if branch == "master":
branch = "main"
else:
branch = branch[len(self.projectName):]
self.knownBranches[branch] = branch
def listExistingP4GitBranches(self):
# branches holds mapping from name to commit
branches = p4BranchesInGit(self.importIntoRemotes)
@@ -1541,8 +1550,10 @@ class P4Sync(Command):
## FIXME - what's a P4 projectName ?
self.projectName = self.guessProjectName()
if not self.hasOrigin:
self.getBranchMapping();
if self.hasOrigin:
self.getBranchMappingFromGitBranches()
else:
self.getBranchMapping()
if self.verbose:
print "p4-git branches: %s" % self.p4BranchesInGit
print "initial parents: %s" % self.initialParents

View File

@@ -27,20 +27,17 @@ import math
import string
import fcntl
have_gtksourceview2 = False
have_gtksourceview = False
try:
import gtksourceview2
have_gtksourceview2 = True
except ImportError:
have_gtksourceview2 = False
try:
import gtksourceview
have_gtksourceview = True
except ImportError:
have_gtksourceview = False
if not have_gtksourceview2 and not have_gtksourceview:
print "Running without gtksourceview2 or gtksourceview module"
try:
import gtksourceview
have_gtksourceview = True
except ImportError:
print "Running without gtksourceview2 or gtksourceview module"
re_ident = re.compile('(author|committer) (?P<ident>.*) (?P<epoch>\d+) (?P<tz>[+-]\d{4})')

View File

@@ -121,7 +121,7 @@ static int queue_diff(struct diff_options *o,
} else {
struct diff_filespec *d1, *d2;
if (o->reverse_diff) {
if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
unsigned tmp;
const char *tmp_c;
tmp = mode1; mode1 = mode2; mode2 = tmp;
@@ -189,8 +189,8 @@ static int handle_diff_files_args(struct rev_info *revs,
else if (!strcmp(argv[1], "-n") ||
!strcmp(argv[1], "--no-index")) {
revs->max_count = -2;
revs->diffopt.exit_with_status = 1;
revs->diffopt.no_index = 1;
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
}
else if (!strcmp(argv[1], "-q"))
*options |= DIFF_SILENT_ON_REMOVED;
@@ -208,7 +208,7 @@ static int handle_diff_files_args(struct rev_info *revs,
if (!is_in_index(revs->diffopt.paths[0]) ||
!is_in_index(revs->diffopt.paths[1])) {
revs->max_count = -2;
revs->diffopt.no_index = 1;
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
}
}
@@ -263,7 +263,7 @@ int setup_diff_no_index(struct rev_info *revs,
break;
} else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
i = argc - 3;
revs->diffopt.exit_with_status = 1;
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
break;
}
if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
@@ -301,7 +301,7 @@ int setup_diff_no_index(struct rev_info *revs,
else
revs->diffopt.paths = argv + argc - 2;
revs->diffopt.nr_paths = 2;
revs->diffopt.no_index = 1;
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
revs->max_count = -2;
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
@@ -315,7 +315,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
if (handle_diff_files_args(revs, argc, argv, &options))
return -1;
if (revs->diffopt.no_index) {
if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) {
if (revs->diffopt.nr_paths != 2)
return error("need two files/directories with --no-index");
if (queue_diff(&revs->diffopt, revs->diffopt.paths[0],
@@ -354,7 +354,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
struct cache_entry *ce = active_cache[i];
int changed;
if (revs->diffopt.quiet && revs->diffopt.has_changes)
if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
if (!ce_path_match(ce, revs->prune_data))
@@ -450,7 +451,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
}
changed = ce_match_stat(ce, &st, ce_option);
if (!changed && !revs->diffopt.find_copies_harder)
if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
oldmode = ntohl(ce->ce_mode);
newmode = ntohl(ce_mode_from_stat(ce, st.st_mode));
@@ -569,7 +570,7 @@ static int show_modified(struct rev_info *revs,
oldmode = old->ce_mode;
if (mode == oldmode && !hashcmp(sha1, old->sha1) &&
!revs->diffopt.find_copies_harder)
!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
return 0;
mode = ntohl(mode);
@@ -589,7 +590,8 @@ static int diff_cache(struct rev_info *revs,
struct cache_entry *ce = *ac;
int same = (entries > 1) && ce_same_name(ce, ac[1]);
if (revs->diffopt.quiet && revs->diffopt.has_changes)
if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
if (!ce_path_match(ce, pathspec))

223
diff.c
View File

@@ -814,10 +814,10 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
}
/* Find the longest filename and max number of changes */
reset = diff_get_color(options->color_diff, DIFF_RESET);
set = diff_get_color(options->color_diff, DIFF_PLAIN);
add_c = diff_get_color(options->color_diff, DIFF_FILE_NEW);
del_c = diff_get_color(options->color_diff, DIFF_FILE_OLD);
reset = diff_get_color_opt(options, DIFF_RESET);
set = diff_get_color_opt(options, DIFF_PLAIN);
add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
for (i = 0; i < data->nr; i++) {
struct diffstat_file *file = data->files[i];
@@ -1243,8 +1243,8 @@ static void builtin_diff(const char *name_a,
mmfile_t mf1, mf2;
const char *lbl[2];
char *a_one, *b_two;
const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
const char *set = diff_get_color_opt(o, DIFF_METAINFO);
const char *reset = diff_get_color_opt(o, DIFF_RESET);
a_one = quote_two("a/", name_a + (*name_a == '/'));
b_two = quote_two("b/", name_b + (*name_b == '/'));
@@ -1277,7 +1277,7 @@ static void builtin_diff(const char *name_a,
goto free_ab_and_return;
if (complete_rewrite) {
emit_rewrite_diff(name_a, name_b, one, two,
o->color_diff);
DIFF_OPT_TST(o, COLOR_DIFF));
o->found_changes = 1;
goto free_ab_and_return;
}
@@ -1286,13 +1286,13 @@ static void builtin_diff(const char *name_a,
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
if (!o->text &&
if (!DIFF_OPT_TST(o, TEXT) &&
(diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) {
/* Quite common confusing case */
if (mf1.size == mf2.size &&
!memcmp(mf1.ptr, mf2.ptr, mf1.size))
goto free_ab_and_return;
if (o->binary)
if (DIFF_OPT_TST(o, BINARY))
emit_binary_diff(&mf1, &mf2);
else
printf("Binary files %s and %s differ\n",
@@ -1315,7 +1315,7 @@ static void builtin_diff(const char *name_a,
memset(&xecfg, 0, sizeof(xecfg));
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.label_path = lbl;
ecbdata.color_diff = o->color_diff;
ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
ecbdata.found_changesp = &o->found_changes;
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
@@ -1331,11 +1331,11 @@ static void builtin_diff(const char *name_a,
ecb.outf = xdiff_outf;
ecb.priv = &ecbdata;
ecbdata.xm.consume = fn_out_consume;
if (o->color_diff_words)
if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
ecbdata.diff_words =
xcalloc(1, sizeof(struct diff_words_data));
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
if (o->color_diff_words)
if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
free_diff_words_data(&ecbdata);
}
@@ -1409,7 +1409,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.xm.consume = checkdiff_consume;
data.filename = name_b ? name_b : name_a;
data.lineno = 0;
data.color_diff = o->color_diff;
data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -1853,7 +1853,7 @@ static void run_diff_cmd(const char *pgm,
struct diff_options *o,
int complete_rewrite)
{
if (!o->allow_external)
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
pgm = NULL;
else {
const char *cmd = external_diff_attr(name);
@@ -1951,9 +1951,9 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
}
if (hashcmp(one->sha1, two->sha1)) {
int abbrev = o->full_index ? 40 : DEFAULT_ABBREV;
int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
if (o->binary) {
if (DIFF_OPT_TST(o, BINARY)) {
mmfile_t mf;
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
@@ -2045,7 +2045,10 @@ void diff_setup(struct diff_options *options)
options->change = diff_change;
options->add_remove = diff_addremove;
options->color_diff = diff_use_color_default;
if (diff_use_color_default)
DIFF_OPT_SET(options, COLOR_DIFF);
else
DIFF_OPT_CLR(options, COLOR_DIFF);
options->detect_rename = diff_detect_rename_default;
}
@@ -2064,7 +2067,7 @@ int diff_setup_done(struct diff_options *options)
if (count > 1)
die("--name-only, --name-status, --check and -s are mutually exclusive");
if (options->find_copies_harder)
if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
options->detect_rename = DIFF_DETECT_COPY;
if (options->output_format & (DIFF_FORMAT_NAME |
@@ -2088,12 +2091,12 @@ int diff_setup_done(struct diff_options *options)
DIFF_FORMAT_SHORTSTAT |
DIFF_FORMAT_SUMMARY |
DIFF_FORMAT_CHECKDIFF))
options->recursive = 1;
DIFF_OPT_SET(options, RECURSIVE);
/*
* Also pickaxe would not work very well if you do not say recursive
*/
if (options->pickaxe)
options->recursive = 1;
DIFF_OPT_SET(options, RECURSIVE);
if (options->detect_rename && options->rename_limit < 0)
options->rename_limit = diff_rename_limit_default;
@@ -2115,9 +2118,9 @@ int diff_setup_done(struct diff_options *options)
* to have found. It does not make sense not to return with
* exit code in such a case either.
*/
if (options->quiet) {
if (DIFF_OPT_TST(options, QUIET)) {
options->output_format = DIFF_FORMAT_NO_OUTPUT;
options->exit_with_status = 1;
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
}
/*
@@ -2125,7 +2128,7 @@ int diff_setup_done(struct diff_options *options)
* upon the first hit. We need to run diff as usual.
*/
if (options->pickaxe || options->filter)
options->quiet = 0;
DIFF_OPT_CLR(options, QUIET);
return 0;
}
@@ -2182,21 +2185,32 @@ static int diff_scoreopt_parse(const char *opt);
int diff_opt_parse(struct diff_options *options, const char **av, int ac)
{
const char *arg = av[0];
/* Output format options */
if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
options->output_format |= DIFF_FORMAT_PATCH;
else if (opt_arg(arg, 'U', "unified", &options->context))
options->output_format |= DIFF_FORMAT_PATCH;
else if (!strcmp(arg, "--raw"))
options->output_format |= DIFF_FORMAT_RAW;
else if (!strcmp(arg, "--patch-with-raw")) {
else if (!strcmp(arg, "--patch-with-raw"))
options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW;
}
else if (!strcmp(arg, "--numstat")) {
else if (!strcmp(arg, "--numstat"))
options->output_format |= DIFF_FORMAT_NUMSTAT;
}
else if (!strcmp(arg, "--shortstat")) {
else if (!strcmp(arg, "--shortstat"))
options->output_format |= DIFF_FORMAT_SHORTSTAT;
}
else if (!strcmp(arg, "--check"))
options->output_format |= DIFF_FORMAT_CHECKDIFF;
else if (!strcmp(arg, "--summary"))
options->output_format |= DIFF_FORMAT_SUMMARY;
else if (!strcmp(arg, "--patch-with-stat"))
options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT;
else if (!strcmp(arg, "--name-only"))
options->output_format |= DIFF_FORMAT_NAME;
else if (!strcmp(arg, "--name-status"))
options->output_format |= DIFF_FORMAT_NAME_STATUS;
else if (!strcmp(arg, "-s"))
options->output_format |= DIFF_FORMAT_NO_OUTPUT;
else if (!prefixcmp(arg, "--stat")) {
char *end;
int width = options->stat_width;
@@ -2224,68 +2238,80 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->stat_name_width = name_width;
options->stat_width = width;
}
else if (!strcmp(arg, "--check"))
options->output_format |= DIFF_FORMAT_CHECKDIFF;
else if (!strcmp(arg, "--summary"))
options->output_format |= DIFF_FORMAT_SUMMARY;
else if (!strcmp(arg, "--patch-with-stat")) {
options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT;
}
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
else if (!prefixcmp(arg, "-l"))
options->rename_limit = strtoul(arg+2, NULL, 10);
else if (!strcmp(arg, "--full-index"))
options->full_index = 1;
else if (!strcmp(arg, "--binary")) {
options->output_format |= DIFF_FORMAT_PATCH;
options->binary = 1;
}
else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) {
options->text = 1;
}
else if (!strcmp(arg, "--name-only"))
options->output_format |= DIFF_FORMAT_NAME;
else if (!strcmp(arg, "--name-status"))
options->output_format |= DIFF_FORMAT_NAME_STATUS;
else if (!strcmp(arg, "-R"))
options->reverse_diff = 1;
else if (!prefixcmp(arg, "-S"))
options->pickaxe = arg + 2;
else if (!strcmp(arg, "-s")) {
options->output_format |= DIFF_FORMAT_NO_OUTPUT;
}
else if (!prefixcmp(arg, "-O"))
options->orderfile = arg + 2;
else if (!prefixcmp(arg, "--diff-filter="))
options->filter = arg + 14;
else if (!strcmp(arg, "--pickaxe-all"))
options->pickaxe_opts = DIFF_PICKAXE_ALL;
else if (!strcmp(arg, "--pickaxe-regex"))
options->pickaxe_opts = DIFF_PICKAXE_REGEX;
/* renames options */
else if (!prefixcmp(arg, "-B")) {
if ((options->break_opt =
diff_scoreopt_parse(arg)) == -1)
if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
return -1;
}
else if (!prefixcmp(arg, "-M")) {
if ((options->rename_score =
diff_scoreopt_parse(arg)) == -1)
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return -1;
options->detect_rename = DIFF_DETECT_RENAME;
}
else if (!prefixcmp(arg, "-C")) {
if (options->detect_rename == DIFF_DETECT_COPY)
options->find_copies_harder = 1;
if ((options->rename_score =
diff_scoreopt_parse(arg)) == -1)
DIFF_OPT_SET(options, FIND_COPIES_HARDER);
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return -1;
options->detect_rename = DIFF_DETECT_COPY;
}
else if (!strcmp(arg, "--no-renames"))
options->detect_rename = 0;
/* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(arg, "--ignore-space-at-eol"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
/* flags options */
else if (!strcmp(arg, "--binary")) {
options->output_format |= DIFF_FORMAT_PATCH;
DIFF_OPT_SET(options, BINARY);
}
else if (!strcmp(arg, "--full-index"))
DIFF_OPT_SET(options, FULL_INDEX);
else if (!strcmp(arg, "-a") || !strcmp(arg, "--text"))
DIFF_OPT_SET(options, TEXT);
else if (!strcmp(arg, "-R"))
DIFF_OPT_SET(options, REVERSE_DIFF);
else if (!strcmp(arg, "--find-copies-harder"))
options->find_copies_harder = 1;
DIFF_OPT_SET(options, FIND_COPIES_HARDER);
else if (!strcmp(arg, "--follow"))
options->follow_renames = 1;
DIFF_OPT_SET(options, FOLLOW_RENAMES);
else if (!strcmp(arg, "--color"))
DIFF_OPT_SET(options, COLOR_DIFF);
else if (!strcmp(arg, "--no-color"))
DIFF_OPT_CLR(options, COLOR_DIFF);
else if (!strcmp(arg, "--color-words"))
options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS;
else if (!strcmp(arg, "--exit-code"))
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
else if (!strcmp(arg, "--quiet"))
DIFF_OPT_SET(options, QUIET);
else if (!strcmp(arg, "--ext-diff"))
DIFF_OPT_SET(options, ALLOW_EXTERNAL);
else if (!strcmp(arg, "--no-ext-diff"))
DIFF_OPT_CLR(options, ALLOW_EXTERNAL);
/* misc options */
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
else if (!prefixcmp(arg, "-l"))
options->rename_limit = strtoul(arg+2, NULL, 10);
else if (!prefixcmp(arg, "-S"))
options->pickaxe = arg + 2;
else if (!strcmp(arg, "--pickaxe-all"))
options->pickaxe_opts = DIFF_PICKAXE_ALL;
else if (!strcmp(arg, "--pickaxe-regex"))
options->pickaxe_opts = DIFF_PICKAXE_REGEX;
else if (!prefixcmp(arg, "-O"))
options->orderfile = arg + 2;
else if (!prefixcmp(arg, "--diff-filter="))
options->filter = arg + 14;
else if (!strcmp(arg, "--abbrev"))
options->abbrev = DEFAULT_ABBREV;
else if (!prefixcmp(arg, "--abbrev=")) {
@@ -2295,28 +2321,6 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
else if (40 < options->abbrev)
options->abbrev = 40;
}
else if (!strcmp(arg, "--color"))
options->color_diff = 1;
else if (!strcmp(arg, "--no-color"))
options->color_diff = 0;
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(arg, "--ignore-space-at-eol"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
else if (!strcmp(arg, "--color-words"))
options->color_diff = options->color_diff_words = 1;
else if (!strcmp(arg, "--no-renames"))
options->detect_rename = 0;
else if (!strcmp(arg, "--exit-code"))
options->exit_with_status = 1;
else if (!strcmp(arg, "--quiet"))
options->quiet = 1;
else if (!strcmp(arg, "--ext-diff"))
options->allow_external = 1;
else if (!strcmp(arg, "--no-ext-diff"))
options->allow_external = 0;
else
return 0;
return 1;
@@ -2712,7 +2716,7 @@ static void diff_summary(struct diff_filepair *p)
break;
default:
if (p->score) {
puts(" rewrite ");
fputs(" rewrite ", stdout);
write_name_quoted(p->two->path, stdout, ' ');
printf("(%d%%)\n", similarity_index(p));
}
@@ -3071,7 +3075,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
* to determine how many paths were dirty only
* due to stat info mismatch.
*/
if (!diffopt->no_index)
if (!DIFF_OPT_TST(diffopt, NO_INDEX))
diffopt->skip_stat_unmatch++;
diff_free_filepair(p);
}
@@ -3082,10 +3086,10 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
void diffcore_std(struct diff_options *options)
{
if (options->quiet)
if (DIFF_OPT_TST(options, QUIET))
return;
if (options->skip_stat_unmatch && !options->find_copies_harder)
if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER))
diffcore_skip_stat_unmatch(options);
if (options->break_opt != -1)
diffcore_break(options->break_opt);
@@ -3100,7 +3104,10 @@ void diffcore_std(struct diff_options *options)
diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
options->has_changes = !!diff_queued_diff.nr;
if (diff_queued_diff.nr)
DIFF_OPT_SET(options, HAS_CHANGES);
else
DIFF_OPT_CLR(options, HAS_CHANGES);
}
@@ -3124,7 +3131,7 @@ void diff_addremove(struct diff_options *options,
* Before the final output happens, they are pruned after
* merged into rename/copy pairs as appropriate.
*/
if (options->reverse_diff)
if (DIFF_OPT_TST(options, REVERSE_DIFF))
addremove = (addremove == '+' ? '-' :
addremove == '-' ? '+' : addremove);
@@ -3139,7 +3146,7 @@ void diff_addremove(struct diff_options *options,
fill_filespec(two, sha1, mode);
diff_queue(&diff_queued_diff, one, two);
options->has_changes = 1;
DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_change(struct diff_options *options,
@@ -3151,7 +3158,7 @@ void diff_change(struct diff_options *options,
char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
if (options->reverse_diff) {
if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
unsigned tmp;
const unsigned char *tmp_c;
tmp = old_mode; old_mode = new_mode; new_mode = tmp;
@@ -3165,7 +3172,7 @@ void diff_change(struct diff_options *options,
fill_filespec(two, new_sha1, new_mode);
diff_queue(&diff_queued_diff, one, two);
options->has_changes = 1;
DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_unmerge(struct diff_options *options,

40
diff.h
View File

@@ -43,26 +43,32 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_FORMAT_CALLBACK 0x1000
#define DIFF_OPT_RECURSIVE (1 << 0)
#define DIFF_OPT_TREE_IN_RECURSIVE (1 << 1)
#define DIFF_OPT_BINARY (1 << 2)
#define DIFF_OPT_TEXT (1 << 3)
#define DIFF_OPT_FULL_INDEX (1 << 4)
#define DIFF_OPT_SILENT_ON_REMOVE (1 << 5)
#define DIFF_OPT_FIND_COPIES_HARDER (1 << 6)
#define DIFF_OPT_FOLLOW_RENAMES (1 << 7)
#define DIFF_OPT_COLOR_DIFF (1 << 8)
#define DIFF_OPT_COLOR_DIFF_WORDS (1 << 9)
#define DIFF_OPT_HAS_CHANGES (1 << 10)
#define DIFF_OPT_QUIET (1 << 11)
#define DIFF_OPT_NO_INDEX (1 << 12)
#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13)
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
#define DIFF_OPT_REVERSE_DIFF (1 << 15)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
struct diff_options {
const char *filter;
const char *orderfile;
const char *pickaxe;
const char *single_follow;
unsigned recursive:1,
tree_in_recursive:1,
binary:1,
text:1,
full_index:1,
silent_on_remove:1,
find_copies_harder:1,
follow_renames:1,
color_diff:1,
color_diff_words:1,
has_changes:1,
quiet:1,
no_index:1,
allow_external:1,
exit_with_status:1;
unsigned flags;
int context;
int break_opt;
int detect_rename;
@@ -71,7 +77,6 @@ struct diff_options {
int output_format;
int pickaxe_opts;
int rename_score;
int reverse_diff;
int rename_limit;
int setup;
int abbrev;
@@ -105,6 +110,9 @@ enum color_diff {
DIFF_WHITESPACE = 7,
};
const char *diff_get_color(int diff_use_color, enum color_diff ix);
#define diff_get_color_opt(o, ix) \
diff_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix)
extern const char mime_boundary_leader[];

6
dir.c
View File

@@ -654,6 +654,7 @@ static void free_simplify(struct path_simplify *simplify)
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
{
struct path_simplify *simplify = create_simplify(pathspec);
char *pp = NULL;
/*
* Make sure to do the per-directory exclude for all the
@@ -661,7 +662,8 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
*/
if (baselen) {
if (dir->exclude_per_dir) {
char *p, *pp = xmalloc(baselen+1);
char *p;
pp = xmalloc(baselen+1);
memcpy(pp, base, baselen+1);
p = pp;
while (1) {
@@ -677,12 +679,12 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
else
p = pp + baselen;
}
free(pp);
}
}
read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
free(pp);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;

View File

@@ -37,10 +37,7 @@ sub list_untracked {
chomp $_;
$_;
}
run_cmd_pipe(qw(git ls-files --others
--exclude-per-directory=.gitignore),
"--exclude-from=$GIT_DIR/info/exclude",
'--', @_);
run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @_);
}
my $status_fmt = '%12s %12s %s';
@@ -567,10 +564,12 @@ sub patch_update_cmd {
IMMEDIATE => 1,
HEADER => $status_head, },
@mods);
return if (!$it);
patch_update_file($it->{VALUE}) if ($it);
}
sub patch_update_file {
my ($ix, $num);
my $path = $it->{VALUE};
my $path = shift;
my ($head, @hunk) = parse_diff($path);
for (@{$head->{TEXT}}) {
print;

View File

@@ -2,11 +2,26 @@
#
# Copyright (c) 2005, 2006 Junio C Hamano
USAGE='[--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
[--3way] [--interactive] [--binary]
[--whitespace=<option>] [-C<n>] [-p<n>]
<mbox>|<Maildir>...
or, when resuming [--skip | --resolved]'
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-am [options] <mbox>|<Maildir>...
git-am [options] --resolved
git-am [options] --skip
--
d,dotest= use <dir> and not .dotest
i,interactive run interactively
b,binary pass --allo-binary-replacement to git-apply
3,3way allow fall back on 3way merging if needed
s,signoff add a Signed-off-by line to the commit message
u,utf8 recode into utf8 (default)
k,keep pass -k flagg to git-mailinfo
whitespace= pass it through git-apply
C= pass it through git-apply
p= pass it through git-apply
resolvemsg= override error message when patch failure occurs
r,resolved to be used after a patch failure
skip skip the current patch"
. git-sh-setup
set_reflog_action am
require_work_tree
@@ -110,49 +125,38 @@ git_apply_opt=
while test $# != 0
do
case "$1" in
-d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*)
dotest=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;;
-d|--d|--do|--dot|--dote|--dotes|--dotest)
case "$#" in 1) usage ;; esac; shift
dotest="$1"; shift;;
-i|--i|--in|--int|--inte|--inter|--intera|--interac|--interact|\
--interacti|--interactiv|--interactive)
interactive=t; shift ;;
-b|--b|--bi|--bin|--bina|--binar|--binary)
binary=t; shift ;;
-3|--3|--3w|--3wa|--3way)
threeway=t; shift ;;
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
sign=t; shift ;;
-u|--u|--ut|--utf|--utf8)
utf8=t; shift ;; # this is now default
--no-u|--no-ut|--no-utf|--no-utf8)
utf8=; shift ;;
-k|--k|--ke|--kee|--keep)
keep=t; shift ;;
-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
resolved=t; shift ;;
--sk|--ski|--skip)
skip=t; shift ;;
--whitespace=*|-C*|-p*)
git_apply_opt="$git_apply_opt $1"; shift ;;
--resolvemsg=*)
resolvemsg=${1#--resolvemsg=}; shift ;;
-i|--interactive)
interactive=t ;;
-b|--binary)
binary=t ;;
-3|--3way)
threeway=t ;;
-s|--signoff)
sign=t ;;
-u|--utf8)
utf8=t ;; # this is now default
--no-utf8)
utf8= ;;
-k|--keep)
keep=t ;;
-r|--resolved)
resolved=t ;;
--skip)
skip=t ;;
-d|--dotest)
shift; dotest=$1;;
--resolvemsg)
shift; resolvemsg=$1 ;;
--whitespace)
git_apply_opt="$git_apply_opt $1=$2"; shift ;;
-C|-p)
git_apply_opt="$git_apply_opt $1$2"; shift ;;
--)
shift; break ;;
-*)
usage ;;
shift; break ;;
*)
break ;;
usage ;;
esac
shift
done
# If the dotest directory exists, but we have finished applying all the

View File

@@ -22,6 +22,7 @@ git bisect log
git bisect run <cmd>...
use <cmd>... to automatically bisect.'
OPTIONS_SPEC=
. git-sh-setup
require_work_tree

View File

@@ -1,6 +1,16 @@
#!/bin/sh
USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
OPTIONS_KEEPDASHDASH=t
OPTIONS_SPEC="\
git-branch [options] [<branch>] [<paths>...]
--
b= create a new branch started at <branch>
l create the new branchs reflog
track tells if the new branch should track the remote branch
f proceed even if the index or working tree is not HEAD
m performa three-way merge on local modifications if needed
q,quiet be quiet
"
SUBDIRECTORY_OK=Sometimes
. git-sh-setup
require_work_tree
@@ -20,13 +30,12 @@ quiet=
v=-v
LF='
'
while [ "$#" != "0" ]; do
arg="$1"
shift
case "$arg" in
"-b")
newbranch="$1"
while test $# != 0; do
case "$1" in
-b)
shift
newbranch="$1"
[ -z "$newbranch" ] &&
die "git checkout: -b needs a branch name"
git show-ref --verify --quiet -- "refs/heads/$newbranch" &&
@@ -34,64 +43,54 @@ while [ "$#" != "0" ]; do
git check-ref-format "heads/$newbranch" ||
die "git checkout: we do not like '$newbranch' as a branch name."
;;
"-l")
-l)
newbranch_log=-l
;;
"--track"|"--no-track")
track="$arg"
--track|--no-track)
track="$1"
;;
"-f")
-f)
force=1
;;
-m)
merge=1
;;
"-q")
-q|--quiet)
quiet=1
v=
;;
--)
shift
break
;;
-*)
usage
;;
*)
if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null)
then
if [ -z "$rev" ]; then
echo "unknown flag $arg"
exit 1
fi
new_name="$arg"
if git show-ref --verify --quiet -- "refs/heads/$arg"
then
rev=$(git rev-parse --verify "refs/heads/$arg^0")
branch="$arg"
fi
new="$rev"
elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
then
# checking out selected paths from a tree-ish.
new="$rev"
new_name="$arg^{tree}"
branch=
else
new=
new_name=
branch=
set x "$arg" "$@"
shift
fi
case "$1" in
--)
shift ;;
esac
break
usage
;;
esac
esac
shift
done
arg="$1"
if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null)
then
[ -z "$rev" ] && die "unknown flag $arg"
new_name="$arg"
if git show-ref --verify --quiet -- "refs/heads/$arg"
then
rev=$(git rev-parse --verify "refs/heads/$arg^0")
branch="$arg"
fi
new="$rev"
shift
elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
then
# checking out selected paths from a tree-ish.
new="$rev"
new_name="$arg^{tree}"
shift
fi
[ "$1" = "--" ] && shift
case "$newbranch,$track" in
,--*)
die "git checkout: --track and --no-track require -b"
@@ -134,12 +133,12 @@ Did you intend to checkout '$@' which can not be resolved as commit?"
fi
# Make sure the request is about existing paths.
git ls-files --error-unmatch -- "$@" >/dev/null || exit
git ls-files -- "$@" |
git checkout-index -f -u --stdin
git ls-files --full-name --error-unmatch -- "$@" >/dev/null || exit
git ls-files --full-name -- "$@" |
(cd_to_toplevel && git checkout-index -f -u --stdin)
# Run a post-checkout hook -- the HEAD does not change so the
# current HEAD is passed in for both args
# Run a post-checkout hook -- the HEAD does not change so the
# current HEAD is passed in for both args
if test -x "$GIT_DIR"/hooks/post-checkout; then
"$GIT_DIR"/hooks/post-checkout $old $old 0
fi
@@ -294,5 +293,5 @@ fi
# Run a post-checkout hook
if test -x "$GIT_DIR"/hooks/post-checkout; then
"$GIT_DIR"/hooks/post-checkout $old $new 1
"$GIT_DIR"/hooks/post-checkout $old $new 1
fi

View File

@@ -3,16 +3,22 @@
# Copyright (c) 2005-2006 Pavel Roskin
#
USAGE="[-d] [-f] [-n] [-q] [-x | -X] [--] <paths>..."
LONG_USAGE='Clean untracked files from the working directory
-d remove directories as well
-f override clean.requireForce and clean anyway
-n don'\''t remove anything, just show what would be done
-q be quiet, only report errors
-x remove ignored files as well
-X remove only ignored files
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-clean [options] <paths>...
Clean untracked files from the working directory
When optional <paths>... arguments are given, the paths
affected are further limited to those that match them.'
affected are further limited to those that match them.
--
d remove directories as well
f override clean.requireForce and clean anyway
n don't remove anything, just show what would be done
q be quiet, only report errors
x remove ignored files as well
X remove only ignored files"
SUBDIRECTORY_OK=Yes
. git-sh-setup
require_work_tree
@@ -56,11 +62,9 @@ do
shift
break
;;
-*)
usage
;;
*)
break
usage # should not happen
;;
esac
shift
done
@@ -77,9 +81,9 @@ case "$disabled" in
;;
esac
case "$ignored,$ignoredonly" in
1,1) usage;;
esac
if [ "$ignored,$ignoredonly" = "1,1" ]; then
die "-x and -X cannot be set together"
fi
if [ -z "$ignored" ]; then
excl="--exclude-per-directory=.gitignore"

View File

@@ -8,6 +8,25 @@
# See git-sh-setup why.
unset CDPATH
OPTIONS_SPEC="\
git-clone [options] [--] <repo> [<dir>]
--
n,no-checkout don't create a checkout
bare create a bare repository
naked create a bare repository
l,local to clone from a local repository
no-hardlinks don't use local hardlinks, always copy
s,shared setup as a shared repository
template= path to the template directory
q,quiet be quiet
reference= reference repository
o,origin= use <name> instead of 'origin' to track upstream
u,upload-pack= path to git-upload-pack on the remote
depth= create a shallow clone of that depth
use-separate-remote compatibility, do not use
no-separate-remote compatibility, do not use"
die() {
echo >&2 "$@"
exit 1
@@ -51,9 +70,11 @@ case $(uname -s) in
esac
usage() {
die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--] <repo> [<dir>]"
exec "$0" -h
}
eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
get_repo_base() {
(
cd "`/bin/pwd -W`" &&
@@ -143,69 +164,59 @@ depth=
no_progress=
test "@@NO_HARDLINKS@@" && use_local_hardlink=no
test -t 1 || no_progress=--no-progress
while
case "$#,$1" in
0,*) break ;;
*,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\
*,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout)
no_checkout=yes ;;
*,--na|*,--nak|*,--nake|*,--naked|\
*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
local_explicitly_asked_for=yes
(test "@@NO_HARDLINKS@@" &&
echo >&2 "Warning: -l asked but hardlinks are not supported") ||
use_local_hardlink=yes ;;
*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
use_local_hardlink=no ;;
*,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
local_shared=yes; ;;
1,--template) usage ;;
*,--template)
while test $# != 0
do
case "$1" in
-n|--no-checkout)
no_checkout=yes ;;
--naked|--bare)
bare=yes ;;
-l|--local)
local_explicitly_asked_for=yes
(test "@@NO_HARDLINKS@@" &&
echo >&2 "Warning: -l asked but hardlinks are not supported") ||
use_local_hardlink=yes
;;
--no-hardlinks)
use_local_hardlink=no ;;
-s|--shared)
local_shared=yes ;;
--template)
shift; template="--template=$1" ;;
*,--template=*)
template="$1" ;;
*,-q|*,--quiet) quiet=-q ;;
*,--use-separate-remote) ;;
*,--no-separate-remote)
-q|--quiet)
quiet=-q ;;
--use-separate-remote|--no-separate-remote)
die "clones are always made with separate-remote layout" ;;
1,--reference) usage ;;
*,--reference)
--reference)
shift; reference="$1" ;;
*,--reference=*)
reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
*,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
case "$2" in
-o,--origin)
shift;
case "$1" in
'')
usage ;;
*/*)
die "'$2' is not suitable for an origin name"
die "'$1' is not suitable for an origin name"
esac
git check-ref-format "heads/$2" ||
die "'$2' is not suitable for a branch name"
git check-ref-format "heads/$1" ||
die "'$1' is not suitable for a branch name"
test -z "$origin_override" ||
die "Do not give more than one --origin options."
origin_override=yes
origin="$2"; shift
origin="$1"
;;
1,-u|1,--upload-pack) usage ;;
*,-u|*,--upload-pack)
-u|--upload-pack)
shift
upload_pack="--upload-pack=$1" ;;
*,--upload-pack=*)
upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
1,--depth) usage;;
*,--depth)
--depth)
shift
depth="--depth=$1";;
*,--)
depth="--depth=$1" ;;
--)
shift
break ;;
*,-*) usage ;;
*) break ;;
*)
usage ;;
esac
do
shift
done

View File

@@ -5,6 +5,7 @@
USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
require_work_tree

View File

@@ -4,10 +4,24 @@
#define _FILE_OFFSET_BITS 64
#ifndef FLEX_ARRAY
#if defined(__GNUC__) && (__GNUC__ < 3)
#define FLEX_ARRAY 0
#else
#define FLEX_ARRAY /* empty */
/*
* See if our compiler is known to support flexible array members.
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEX_ARRAY /* empty */
#elif defined(__GNUC__)
# if (__GNUC__ >= 3)
# define FLEX_ARRAY /* empty */
# else
# define FLEX_ARRAY 0 /* older GNU extension */
# endif
#endif
/*
* Otherwise, default to safer but a bit wasteful traditional style
*/
#ifndef FLEX_ARRAY
# define FLEX_ARRAY 1
#endif
#endif
@@ -20,6 +34,7 @@
#endif
#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
#define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */
/* Approximation of the length of the decimal representation of this type. */
#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)

View File

@@ -92,6 +92,7 @@ USAGE="[--env-filter <command>] [--tree-filter <command>] \
[--original <namespace>] [-d <directory>] [-f | --force] \
[<rev-list options>...]"
OPTIONS_SPEC=
. git-sh-setup
git diff-files --quiet &&

View File

@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=0.8.GITGUI
DEF_VER=0.9.GITGUI
LF='
'

View File

@@ -551,8 +551,15 @@ proc apply_config {} {
set name [lindex $option 0]
set font [lindex $option 1]
if {[catch {
set need_weight 1
foreach {cn cv} $repo_config(gui.$name) {
font configure $font $cn $cv -weight normal
if {$cn eq {-weight}} {
set need_weight 0
}
font configure $font $cn $cv
}
if {$need_weight} {
font configure $font -weight normal
}
} err]} {
error_popup [strcat [mc "Invalid font specified in %s:" "gui.$name"] "\n\n$err"]
@@ -762,7 +769,10 @@ git-version proc _parse_config {arr_name args} {
array unset arr
set buf {}
catch {
set fd_rc [eval [list git_read config --null --list] $args]
set fd_rc [eval \
[list git_read config] \
$args \
[list --null --list]]
fconfigure $fd_rc -translation binary
set buf [read $fd_rc]
close $fd_rc
@@ -1976,7 +1986,8 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
[list .mbar.commit entryconf [.mbar.commit index last] -state]
.mbar.commit add command -label [mc "Stage To Commit"] \
-command do_add_selection
-command do_add_selection \
-accelerator $M1T-T
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
@@ -2628,6 +2639,8 @@ unset gm
# -- Key Bindings
#
bind $ui_comm <$M1B-Key-Return> {do_commit;break}
bind $ui_comm <$M1B-Key-t> {do_add_selection;break}
bind $ui_comm <$M1B-Key-T> {do_add_selection;break}
bind $ui_comm <$M1B-Key-i> {do_add_all;break}
bind $ui_comm <$M1B-Key-I> {do_add_all;break}
bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
@@ -2677,6 +2690,8 @@ bind . <$M1B-Key-r> do_rescan
bind . <$M1B-Key-R> do_rescan
bind . <$M1B-Key-s> do_signoff
bind . <$M1B-Key-S> do_signoff
bind . <$M1B-Key-t> do_add_selection
bind . <$M1B-Key-T> do_add_selection
bind . <$M1B-Key-i> do_add_all
bind . <$M1B-Key-I> do_add_all
bind . <$M1B-Key-Return> do_commit

View File

@@ -253,7 +253,7 @@ proc commit_committree {fd_wt curHEAD msg} {
global repo_config
gets $fd_wt tree_id
if {$tree_id eq {} || [catch {close $fd_wt} err]} {
if {[catch {close $fd_wt} err]} {
error_popup [strcat [mc "write-tree failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index

View File

@@ -120,7 +120,7 @@ method _read {fd after} {
} else {
$w_t delete $console_cr end
$w_t insert end "\n"
$w_t insert end [string range $buf $c $cr]
$w_t insert end [string range $buf $c [expr {$cr - 1}]]
set c $cr
incr c
}

View File

@@ -1,6 +1,56 @@
# git-gui index (add/remove) support
# Copyright (C) 2006, 2007 Shawn Pearce
proc _delete_indexlock {} {
if {[catch {file delete -- [gitdir index.lock]} err]} {
error_popup [strcat [mc "Unable to unlock the index."] "\n\n$err"]
}
}
proc _close_updateindex {fd after} {
fconfigure $fd -blocking 1
if {[catch {close $fd} err]} {
set w .indexfried
toplevel $w
wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]]
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
pack [label $w.msg \
-justify left \
-anchor w \
-text [strcat \
[mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] \
"\n\n$err"] \
] -anchor w
frame $w.buttons
button $w.buttons.continue \
-text [mc "Continue"] \
-command [list destroy $w]
pack $w.buttons.continue -side right -padx 5
button $w.buttons.unlock \
-text [mc "Unlock Index"] \
-command "destroy $w; _delete_indexlock"
pack $w.buttons.unlock -side right
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
wm protocol $w WM_DELETE_WINDOW update
bind $w.buttons.continue <Visibility> "
grab $w
focus $w.buttons.continue
"
tkwait window $w
$::main_status stop
unlock_index
rescan $after 0
return
}
$::main_status stop
unlock_index
uplevel #0 $after
}
proc update_indexinfo {msg pathList after} {
global update_index_cp
@@ -35,10 +85,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch after} {
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
$::main_status stop
uplevel #0 $after
_close_updateindex $fd $after
return
}
@@ -100,10 +147,7 @@ proc write_update_index {fd pathList totalCnt batch after} {
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
$::main_status stop
uplevel #0 $after
_close_updateindex $fd $after
return
}
@@ -175,10 +219,7 @@ proc write_checkout_index {fd pathList totalCnt batch after} {
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
$::main_status stop
uplevel #0 $after
_close_updateindex $fd $after
return
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,8 +6,8 @@
msgid ""
msgstr ""
"Project-Id-Version: git-gui glossary\n"
"POT-Creation-Date: 2007-10-05 22:30+0200\n"
"PO-Revision-Date: 2007-10-05 22:32+0200\n"
"POT-Creation-Date: 2007-10-19 21:43+0200\n"
"PO-Revision-Date: 2007-10-20 15:24+0200\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German \n"
"MIME-Version: 1.0\n"
@@ -108,9 +108,9 @@ msgstr "zusammenführen"
msgid "message"
msgstr "Beschreibung (Meldung?, Nachricht?; Source Safe: Kommentar)"
#. ""
#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
msgid "prune"
msgstr "löschen"
msgstr "entfernen"
#. "Pulling a branch means to fetch it and merge it."
msgid "pull"
@@ -118,12 +118,16 @@ msgstr "übernehmen (ziehen?)"
#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
msgid "push"
msgstr "ausliefern (hochladen? verschicken? schieben?)"
msgstr "versenden (ausliefern? hochladen? verschicken? schieben?)"
#. ""
msgid "redo"
msgstr "wiederholen"
#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
msgid "remote"
msgstr "Andere Archive (Gegenseite?, Entfernte?, Server?)"
#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
msgid "repository"
msgstr "Projektarchiv"

View File

@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2007-10-05 22:30+0200\n"
"POT-Creation-Date: 2007-10-19 21:43+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -86,7 +86,7 @@ msgstr ""
msgid "message"
msgstr ""
#. ""
#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
msgid "prune"
msgstr ""
@@ -102,6 +102,10 @@ msgstr ""
msgid "redo"
msgstr ""
#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
msgid "remote"
msgstr ""
#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
msgid "repository"
msgstr ""

View File

@@ -16,10 +16,11 @@
"merge [noun]" "A successful merge results in the creation of a new commit representing the result of the merge."
"merge [verb]" "To bring the contents of another branch into the current branch."
"message" ""
"prune" ""
"prune" "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
"pull" "Pulling a branch means to fetch it and merge it."
"push" "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
"redo" ""
"remote" "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
"repository" "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
"reset" ""
"revert" ""

View File

View File

@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-10-10 04:04-0400\n"
"PO-Revision-Date: 2007-08-14 18:49+0900\n"
"PO-Revision-Date: 2007-10-31 16:23+0900\n"
"Last-Translator: しらいし ななこ <nanako3@bluebottle.com>\n"
"Language-Team: Japanese\n"
"MIME-Version: 1.0\n"
@@ -19,12 +19,12 @@ msgstr ""
#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744
#: git-gui.sh:763
msgid "git-gui: fatal error"
msgstr ""
msgstr "git-gui: 致命的なエラー"
#: git-gui.sh:595
#, fuzzy, tcl-format
#, tcl-format
msgid "Invalid font specified in %s:"
msgstr "gui.%s に無効なフォントが指定されています:"
msgstr "%s に無効なフォントが指定されています:"
#: git-gui.sh:620
msgid "Main Font"
@@ -66,9 +66,8 @@ msgid "Git directory not found:"
msgstr "Git ディレクトリが見つかりません:"
#: git-gui.sh:860
#, fuzzy
msgid "Cannot move to top of working directory:"
msgstr "変な .git ディレクトリは使えません"
msgstr "作業ディレクトリの最上位に移動できません"
#: git-gui.sh:867
msgid "Cannot use funny .git directory:"
@@ -158,7 +157,6 @@ msgid "Branch"
msgstr "ブランチ"
#: git-gui.sh:1794 lib/choose_rev.tcl:547
#, fuzzy
msgid "Commit@@noun"
msgstr "コミット"
@@ -167,9 +165,8 @@ msgid "Merge"
msgstr "マージ"
#: git-gui.sh:1798 lib/choose_rev.tcl:556
#, fuzzy
msgid "Remote"
msgstr "リモート:"
msgstr "リモート"
#: git-gui.sh:1807
msgid "Browse Current Branch's Files"
@@ -301,7 +298,6 @@ msgid "Sign Off"
msgstr "署名"
#: git-gui.sh:1980 git-gui.sh:2296
#, fuzzy
msgid "Commit@@verb"
msgstr "コミット"
@@ -329,7 +325,7 @@ msgstr "%s について"
#: git-gui.sh:2026
msgid "Preferences..."
msgstr ""
msgstr "設定…"
#: git-gui.sh:2034 git-gui.sh:2558
msgid "Options..."
@@ -346,21 +342,19 @@ msgstr "オンライン・ドキュメント"
#: git-gui.sh:2165
#, tcl-format
msgid "fatal: cannot stat path %s: No such file or directory"
msgstr ""
msgstr "致命的: パス %s が stat できません。そのようなファイルやディレクトリはありません"
#: git-gui.sh:2198
msgid "Current Branch:"
msgstr "現在のブランチ"
#: git-gui.sh:2219
#, fuzzy
msgid "Staged Changes (Will Commit)"
msgstr "ステージングされた(コミット予定済の)変更"
#: git-gui.sh:2239
#, fuzzy
msgid "Unstaged Changes"
msgstr "変更をコミット予定に入れる"
msgstr "コミット予定に入っていない変更"
#: git-gui.sh:2286
msgid "Stage Changed"
@@ -448,6 +442,10 @@ msgid ""
"by %s:\n"
"\n"
msgstr ""
"環境に問題がある可能性があります\n"
"\n"
"以下の環境変数は %s が起動する Git サブプロセスによって無視されるでしょう:\n"
"\n"
#: git-gui.sh:2707
msgid ""
@@ -455,6 +453,9 @@ msgid ""
"This is due to a known issue with the\n"
"Tcl binary distributed by Cygwin."
msgstr ""
"\n"
"これは Cygwin で配布されている Tcl バイナリに\n"
"関しての既知の問題によります"
#: git-gui.sh:2712
#, tcl-format
@@ -466,6 +467,10 @@ msgid ""
"user.email settings into your personal\n"
"~/.gitconfig file.\n"
msgstr ""
"\n"
"\n"
"個人的な ~/.gitconfig ファイル内で user.name と user.email の値を設定\n"
"するのが、%s の良い代用となります\n"
#: lib/about.tcl:25
msgid "git-gui - a graphical user interface for Git."
@@ -490,50 +495,47 @@ msgstr "%s を読んでいます…"
#: lib/blame.tcl:473
msgid "Loading copy/move tracking annotations..."
msgstr ""
msgstr "コピー・移動追跡データを読んでいます…"
#: lib/blame.tcl:493
msgid "lines annotated"
msgstr ""
msgstr "行を注釈しました"
#: lib/blame.tcl:674
msgid "Loading original location annotations..."
msgstr ""
msgstr "元位置行の注釈データを読んでいます…"
#: lib/blame.tcl:677
msgid "Annotation complete."
msgstr ""
msgstr "注釈完了しました"
#: lib/blame.tcl:731
#, fuzzy
msgid "Loading annotation..."
msgstr "%s をロード中…"
msgstr "注釈を読み込んでいます…"
#: lib/blame.tcl:787
msgid "Author:"
msgstr ""
msgstr "作者:"
#: lib/blame.tcl:791
#, fuzzy
msgid "Committer:"
msgstr "コミット:"
msgstr "コミット:"
#: lib/blame.tcl:796
msgid "Original File:"
msgstr ""
msgstr "元ファイル"
#: lib/blame.tcl:910
msgid "Originally By:"
msgstr ""
msgstr "原作者:"
#: lib/blame.tcl:916
#, fuzzy
msgid "In File:"
msgstr "ファイル:"
#: lib/blame.tcl:921
msgid "Copied Or Moved Here By:"
msgstr ""
msgstr "複写・移動者:"
#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
msgid "Checkout Branch"
@@ -741,7 +743,7 @@ msgstr "%s から %s をフェッチしています"
#: lib/checkout_op.tcl:127
#, tcl-format
msgid "fatal: Cannot resolve %s"
msgstr ""
msgstr "致命的エラー: %s を解決できません"
#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
msgid "Close"
@@ -796,9 +798,9 @@ msgstr ""
"自動的に再スキャンを開始します。\n"
#: lib/checkout_op.tcl:322
#, fuzzy, tcl-format
#, tcl-format
msgid "Updating working directory to '%s'..."
msgstr "作業ディレクトリがありません"
msgstr "作業ディレクトリを '%s' に更新しています…"
#: lib/checkout_op.tcl:353
#, tcl-format
@@ -827,9 +829,9 @@ msgstr ""
"チを開始してください。"
#: lib/checkout_op.tcl:446
#, fuzzy, tcl-format
#, tcl-format
msgid "Checked out '%s'."
msgstr "チェックアウト"
msgstr "'%s' をチェックアウトしました"
#: lib/checkout_op.tcl:478
#, tcl-format
@@ -866,244 +868,235 @@ msgstr ""
"起こるはずのないエラーです。あきらめて %s を終了します。"
#: lib/choose_font.tcl:39
#, fuzzy
msgid "Select"
msgstr "全て選択"
msgstr "選択"
#: lib/choose_font.tcl:53
msgid "Font Family"
msgstr ""
msgstr "フォント・ファミリー"
#: lib/choose_font.tcl:73
#, fuzzy
msgid "Font Size"
msgstr "フォントを小さく"
msgstr "フォントの大きさ"
#: lib/choose_font.tcl:90
msgid "Font Example"
msgstr ""
msgstr "フォント・サンプル"
#: lib/choose_font.tcl:101
msgid ""
"This is example text.\n"
"If you like this text, it can be your font."
msgstr ""
"これはサンプル文です。\n"
"このフォントが気に入ればお使いになれます。"
#: lib/choose_repository.tcl:25
msgid "Git Gui"
msgstr ""
msgstr "Git GUI"
#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
#, fuzzy
msgid "Create New Repository"
msgstr "元のリポジトリ"
msgstr "新しいリポジトリを作る"
#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
#, fuzzy
msgid "Clone Existing Repository"
msgstr "送り先リポジトリ"
msgstr "既存リポジトリを複製する"
#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
#, fuzzy
msgid "Open Existing Repository"
msgstr "送り先リポジトリ"
msgstr "既存リポジトリを開く"
#: lib/choose_repository.tcl:91
msgid "Next >"
msgstr ""
msgstr "次 >"
#: lib/choose_repository.tcl:152
#, fuzzy, tcl-format
#, tcl-format
msgid "Location %s already exists."
msgstr "'%s'というブランチは既に存在します。"
msgstr "'%s' は既に存在します。"
#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
#: lib/choose_repository.tcl:172
#, fuzzy, tcl-format
#, tcl-format
msgid "Failed to create repository %s:"
msgstr "完全にオプションを保存できません:"
msgstr "リポジトリ %s を作製できません:"
#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
msgid "Directory:"
msgstr ""
msgstr "ディレクトリ:"
#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
#: lib/choose_repository.tcl:834
#, fuzzy
msgid "Git Repository"
msgstr "リポジトリ"
msgstr "GIT リポジトリ"
#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
#, fuzzy, tcl-format
#, tcl-format
msgid "Directory %s already exists."
msgstr "'%s'というブランチは既に存在します。"
msgstr "ディレクトリ '%s' は既に存在します。"
#: lib/choose_repository.tcl:265
#, fuzzy, tcl-format
#, tcl-format
msgid "File %s already exists."
msgstr "'%s'というブランチは既に存在します。"
msgstr "ファイル '%s' は既に存在します。"
#: lib/choose_repository.tcl:286
#, fuzzy
msgid "Clone"
msgstr "閉じる"
msgstr "複製"
#: lib/choose_repository.tcl:299
msgid "URL:"
msgstr ""
msgstr "URL:"
#: lib/choose_repository.tcl:319
msgid "Clone Type:"
msgstr ""
msgstr "複製方式:"
#: lib/choose_repository.tcl:325
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
msgstr ""
msgstr "標準(高速・中冗長度・ハードリンク)"
#: lib/choose_repository.tcl:331
msgid "Full Copy (Slower, Redundant Backup)"
msgstr ""
msgstr "全複写(低速・冗長バックアップ)"
#: lib/choose_repository.tcl:337
msgid "Shared (Fastest, Not Recommended, No Backup)"
msgstr ""
msgstr "共有(最高速・非推奨・バックアップ無し)"
#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418
#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630
#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848
#, fuzzy, tcl-format
#, tcl-format
msgid "Not a Git repository: %s"
msgstr "リポジトリが選択されていません。"
msgstr "Git リポジトリではありません: %s"
#: lib/choose_repository.tcl:405
msgid "Standard only available for local repository."
msgstr ""
msgstr "標準方式は同一計算機上のリポジトリにのみ使えます。"
#: lib/choose_repository.tcl:409
msgid "Shared only available for local repository."
msgstr ""
msgstr "共有方式は同一計算機上のリポジトリにのみ使えます。"
#: lib/choose_repository.tcl:439
msgid "Failed to configure origin"
msgstr ""
msgstr "origin を設定できませんでした"
#: lib/choose_repository.tcl:451
msgid "Counting objects"
msgstr ""
msgstr "オブジェクトを数えています"
#: lib/choose_repository.tcl:452
msgid "buckets"
msgstr ""
msgstr "バケツ"
#: lib/choose_repository.tcl:476
#, tcl-format
msgid "Unable to copy objects/info/alternates: %s"
msgstr ""
msgstr "objects/info/alternates を複写できません: %s"
#: lib/choose_repository.tcl:512
#, fuzzy, tcl-format
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "%s から新しい変更をフェッチしています"
msgstr "%s から複製する内容はありません"
#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728
#: lib/choose_repository.tcl:740
msgid "The 'master' branch has not been initialized."
msgstr ""
msgstr "'master' ブランチが初期化されていません"
#: lib/choose_repository.tcl:527
msgid "Hardlinks are unavailable. Falling back to copying."
msgstr ""
msgstr "ハードリンクが作れないので、コピーします"
#: lib/choose_repository.tcl:539
#, fuzzy, tcl-format
#, tcl-format
msgid "Cloning from %s"
msgstr "%s から %s をフェッチしています"
msgstr "%s から複製しています"
#: lib/choose_repository.tcl:570
#, fuzzy
msgid "Copying objects"
msgstr "データベース圧縮"
msgstr "オブジェクトを複写しています"
#: lib/choose_repository.tcl:571
msgid "KiB"
msgstr ""
msgstr "KiB"
#: lib/choose_repository.tcl:595
#, tcl-format
msgid "Unable to copy object: %s"
msgstr ""
msgstr "オブジェクトを複写できません: %s"
#: lib/choose_repository.tcl:605
msgid "Linking objects"
msgstr ""
msgstr "オブジェクトを連結しています"
#: lib/choose_repository.tcl:606
msgid "objects"
msgstr ""
msgstr "オブジェクト"
#: lib/choose_repository.tcl:614
#, tcl-format
msgid "Unable to hardlink object: %s"
msgstr ""
msgstr "オブジェクトをハードリンクできません: %s"
#: lib/choose_repository.tcl:669
msgid "Cannot fetch branches and objects. See console output for details."
msgstr ""
msgstr "ブランチやオブジェクトを取得できません。コンソール出力を見て下さい"
#: lib/choose_repository.tcl:680
msgid "Cannot fetch tags. See console output for details."
msgstr ""
msgstr "タグを取得できません。コンソール出力を見て下さい"
#: lib/choose_repository.tcl:704
msgid "Cannot determine HEAD. See console output for details."
msgstr ""
msgstr "HEAD を確定できません。コンソール出力を見て下さい"
#: lib/choose_repository.tcl:713
#, tcl-format
msgid "Unable to cleanup %s"
msgstr ""
msgstr "%s を掃除できません"
#: lib/choose_repository.tcl:719
#, fuzzy
msgid "Clone failed."
msgstr "中断に失敗しました。"
msgstr "複写に失敗しました。"
#: lib/choose_repository.tcl:726
msgid "No default branch obtained."
msgstr ""
msgstr "デフォールト・ブランチが取得されませんでした"
#: lib/choose_repository.tcl:737
#, tcl-format
msgid "Cannot resolve %s as a commit."
msgstr ""
msgstr "%s をコミットとして解釈できません"
#: lib/choose_repository.tcl:749
#, fuzzy
msgid "Creating working directory"
msgstr "作業ディレクトリがありません"
msgstr "作業ディレクトリを作成しています"
#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
#: lib/index.tcl:149
msgid "files"
msgstr ""
msgstr "ファイル"
#: lib/choose_repository.tcl:779
msgid "Initial file checkout failed."
msgstr ""
msgstr "初期チェックアウトに失敗しました"
#: lib/choose_repository.tcl:795
msgid "Open"
msgstr ""
msgstr "開く"
#: lib/choose_repository.tcl:805
#, fuzzy
msgid "Repository:"
msgstr "リポジトリ"
msgstr "リポジトリ:"
#: lib/choose_repository.tcl:854
#, fuzzy, tcl-format
#, tcl-format
msgid "Failed to open repository %s:"
msgstr "完全にオプションを保存できません:"
msgstr "リポジトリ %s を開けません:"
#: lib/choose_rev.tcl:53
msgid "This Detached Checkout"
@@ -1140,11 +1133,11 @@ msgstr "リビジョン式が空です。"
#: lib/choose_rev.tcl:530
msgid "Updated"
msgstr ""
msgstr "更新しました"
#: lib/choose_rev.tcl:558
msgid "URL"
msgstr ""
msgstr "URL"
#: lib/commit.tcl:9
msgid ""
@@ -1258,7 +1251,7 @@ msgstr "write-tree が失敗しました:"
#: lib/commit.tcl:275
#, tcl-format
msgid "Commit %s appears to be corrupt"
msgstr ""
msgstr "コミット %s は壊れています"
#: lib/commit.tcl:279
msgid ""
@@ -1281,7 +1274,7 @@ msgstr "コミットする変更がありません。"
#: lib/commit.tcl:303
#, tcl-format
msgid "warning: Tcl does not support encoding '%s'."
msgstr ""
msgstr "警告: Tcl はエンコーディング '%s' をサポートしていません"
#: lib/commit.tcl:317
msgid "commit-tree failed:"
@@ -1354,11 +1347,16 @@ msgid ""
"\n"
"Compress the database now?"
msgstr ""
"このリポジトリにはおおよそ %i 個の個別オブジェクトがあります\n"
"\n"
"最適な性能を保つために、%i 個以上の個別オブジェクトを作る毎にデータベースを圧縮することを推奨します\n"
"\n"
"データベースを圧縮しますか?"
#: lib/date.tcl:25
#, fuzzy, tcl-format
#, tcl-format
msgid "Invalid date from Git: %s"
msgstr "無効なリビジョン: %s"
msgstr "Git から出た無効な日付: %s"
#: lib/diff.tcl:42
#, tcl-format
@@ -1383,14 +1381,14 @@ msgstr ""
"同様な状態のファイルを探すために、自動的に再スキャンを開始します。"
#: lib/diff.tcl:81
#, fuzzy, tcl-format
#, tcl-format
msgid "Loading diff of %s..."
msgstr "%s をロード中…"
msgstr "%s の変更点をロード中…"
#: lib/diff.tcl:114 lib/diff.tcl:184
#, tcl-format
msgid "Unable to display %s"
msgstr ""
msgstr "%s を表示できません"
#: lib/diff.tcl:115
msgid "Error loading file:"
@@ -1398,11 +1396,11 @@ msgstr "ファイルを読む際のエラーです:"
#: lib/diff.tcl:122
msgid "Git Repository (subproject)"
msgstr ""
msgstr "Git リポジトリ(サブプロジェクト)"
#: lib/diff.tcl:134
msgid "* Binary file (not showing content)."
msgstr ""
msgstr "* バイナリファイル(内容は表示しません)"
#: lib/diff.tcl:185
msgid "Error loading diff:"
@@ -1429,14 +1427,14 @@ msgid "You must correct the above errors before committing."
msgstr "コミットする前に、以上のエラーを修正して下さい"
#: lib/index.tcl:241
#, fuzzy, tcl-format
#, tcl-format
msgid "Unstaging %s from commit"
msgstr "コミットから降ろす"
msgstr "コミットから '%s' を降ろす"
#: lib/index.tcl:285
#, fuzzy, tcl-format
#, tcl-format
msgid "Adding %s"
msgstr "%s を読んでいます"
msgstr "コミットに %s を加えています"
#: lib/index.tcl:340
#, tcl-format
@@ -1651,41 +1649,37 @@ msgid "New Branch Name Template"
msgstr "新しいブランチ名のテンプレート"
#: lib/option.tcl:176
#, fuzzy
msgid "Change Font"
msgstr "フォント"
msgstr "フォントを変更"
#: lib/option.tcl:180
#, tcl-format
msgid "Choose %s"
msgstr ""
msgstr "%s を選択"
#: lib/option.tcl:186
msgid "pt."
msgstr ""
msgstr "ポイント"
#: lib/option.tcl:200
msgid "Preferences"
msgstr ""
msgstr "設定"
#: lib/option.tcl:235
msgid "Failed to completely save options:"
msgstr "完全にオプションを保存できません:"
#: lib/remote.tcl:165
#, fuzzy
msgid "Prune from"
msgstr "%s から刈…"
msgstr "から刈込む…"
#: lib/remote.tcl:170
#, fuzzy
msgid "Fetch from"
msgstr "%s からフェッチ…"
msgstr "取得元"
#: lib/remote.tcl:213
#, fuzzy
msgid "Push to"
msgstr "プッシュ"
msgstr "プッシュ"
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch"
@@ -1724,12 +1718,15 @@ msgid "A branch is required for 'Merged Into'."
msgstr "'マージ先' にはブランチが必要です。"
#: lib/remote_branch_delete.tcl:184
#, fuzzy, tcl-format
#, tcl-format
msgid ""
"The following branches are not completely merged into %s:\n"
"\n"
" - %s"
msgstr "以下のブランチは %s に完全にマージされていません:"
msgstr ""
"以下のブランチは %s に完全にマージされていません:\n"
"\n"
" - %s"
#: lib/remote_branch_delete.tcl:189
#, tcl-format
@@ -1779,12 +1776,12 @@ msgstr "アイコンが書けません:"
#: lib/status_bar.tcl:83
#, tcl-format
msgid "%s ... %*i of %*i %s (%3i%%)"
msgstr "%1$s ... %3$*i %4$s 中の %$2*i (%5$3i%%)"
msgstr "%1$s ... %4$*i %6$s 中の %2$*i (%7$3i%%)"
#: lib/transport.tcl:6
#, fuzzy, tcl-format
#, tcl-format
msgid "fetch %s"
msgstr "フェッチ"
msgstr "%s を取得"
#: lib/transport.tcl:7
#, tcl-format
@@ -1794,7 +1791,7 @@ msgstr "%s から新しい変更をフェッチしています"
#: lib/transport.tcl:18
#, tcl-format
msgid "remote prune %s"
msgstr ""
msgstr "遠隔刈込 %s"
#: lib/transport.tcl:19
#, tcl-format
@@ -1804,7 +1801,7 @@ msgstr "%s から削除されたトラッキング・ブランチを刈ってい
#: lib/transport.tcl:25 lib/transport.tcl:71
#, tcl-format
msgid "push %s"
msgstr ""
msgstr "%s をプッシュ"
#: lib/transport.tcl:26
#, tcl-format
@@ -1834,7 +1831,7 @@ msgstr "通信オプション"
#: lib/transport.tcl:160
msgid "Force overwrite existing branch (may discard changes)"
msgstr ""
msgstr "既存ブランチを上書き(変更を破棄する可能性があります)"
#: lib/transport.tcl:164
msgid "Use thin pack (for slow network connections)"
@@ -1844,11 +1841,3 @@ msgstr "Thin Pack を使う(遅いネットワーク接続)"
msgid "Include tags"
msgstr "タグを含める"
#~ msgid "Cannot find the git directory:"
#~ msgstr "git ディレクトリが見つかりません:"
#~ msgid "Unstaged Changes (Will Not Be Committed)"
#~ msgstr "ステージングされていない(コミット未予定の)変更"
#~ msgid "Push to %s..."
#~ msgstr "%s へプッシュ…"

View File

@@ -26,11 +26,17 @@ proc u2a {s} {
set output_directory "."
set lang "dummy"
set files [list]
set show_statistics 0
# parse options
for {set i 1} {$i < $argc} {incr i} {
for {set i 0} {$i < $argc} {incr i} {
set arg [lindex $argv $i]
if {$arg == "--statistics" || $arg == "--tcl"} {
if {$arg == "--statistics"} {
incr show_statistics
continue
}
if {$arg == "--tcl"} {
# we know
continue
}
if {$arg == "-l"} {
@@ -48,22 +54,37 @@ for {set i 1} {$i < $argc} {incr i} {
}
proc flush_msg {} {
global msgid msgstr mode lang out
global msgid msgstr mode lang out fuzzy
global translated_count fuzzy_count not_translated_count
if {![info exists msgid] || $mode == ""} {
return
}
set mode ""
if {$fuzzy == 1} {
incr fuzzy_count
set fuzzy 0
return
}
if {$msgid == ""} {
set prefix "set ::msgcat::header"
} else {
if {$msgstr == ""} {
incr not_translated_count
return
}
set prefix "::msgcat::mcset $lang \"[u2a $msgid]\""
incr translated_count
}
puts $out "$prefix \"[u2a $msgstr]\""
}
set fuzzy 0
set translated_count 0
set fuzzy_count 0
set not_translated_count 0
foreach file $files {
regsub "^.*/\(\[^/\]*\)\.po$" $file "$output_directory\\1.msg" outfile
set in [open $file "r"]
@@ -73,7 +94,11 @@ foreach file $files {
set mode ""
while {[gets $in line] >= 0} {
if {[regexp "^#" $line]} {
flush_msg
if {[regexp ", fuzzy" $line]} {
set fuzzy 1
} else {
flush_msg
}
continue
} elseif {[regexp "^msgid \"(.*)\"$" $line dummy match]} {
flush_msg
@@ -101,3 +126,8 @@ foreach file $files {
close $out
}
if {$show_statistics} {
puts [concat "$translated_count translated messages, " \
"$fuzzy_count fuzzy ones, " \
"$not_translated_count untranslated ones."]
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,21 @@
#
# Copyright (c) 2006 Eric Wong
#
USAGE='[--start] [--stop] [--restart]
[--local] [--httpd=<httpd>] [--port=<port>] [--browser=<browser>]
[--module-path=<path> (for Apache2 only)]'
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-instaweb [options] (--start | --stop | --restart)
--
l,local only bind on 127.0.0.1
p,port= the port to bind to
d,httpd= the command to launch
b,browser= the browser to launch
m,module-path= the module path (only needed for apache2)
Action
stop stop the web server
start start the web server
restart restart the web server
"
. git-sh-setup
@@ -78,52 +90,26 @@ do
start_httpd
exit 0
;;
--local|-l)
-l|--local)
local=true
;;
-d|--httpd|--httpd=*)
case "$#,$1" in
*,*=*)
httpd=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
httpd="$2"
shift ;;
esac
-d|--httpd)
shift
httpd="$1"
;;
-b|--browser|--browser=*)
case "$#,$1" in
*,*=*)
browser=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
browser="$2"
shift ;;
esac
-b|--browser)
shift
browser="$1"
;;
-p|--port|--port=*)
case "$#,$1" in
*,*=*)
port=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
port="$2"
shift ;;
esac
-p|--port)
shift
port="$1"
;;
-m|--module-path=*|--module-path)
case "$#,$1" in
*,*=*)
module_path=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
module_path="$2"
shift ;;
esac
-m|--module-path)
shift
module_path="$1"
;;
--)
;;
*)
usage

View File

@@ -2,6 +2,7 @@
USAGE=''
SUBDIRECTORY_OK='Yes'
OPTIONS_SPEC=
. git-sh-setup
echo "WARNING: '$0' is deprecated in favor of 'git fsck --lost-found'" >&2

View File

@@ -3,7 +3,19 @@
# Copyright (c) 2005 Junio C Hamano
#
USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s <strategy>] [-m=<merge-message>] <commit>+'
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-merge [options] <remote>...
git-merge [options] <msg> HEAD <remote>
--
summary show a diffstat at the end of the merge
n,no-summary don't show a diffstat at the end of the merge
squash create a single commit instead of doing a merge
commit perform a commit if the merge sucesses (default)
ff allow fast forward (default)
s,strategy= merge strategy to use
m,message= message to be used for the merge commit (if any)
"
SUBDIRECTORY_OK=Yes
. git-sh-setup
@@ -150,72 +162,47 @@ merge_name () {
fi
}
parse_option () {
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
show_diffstat=false ;;
--summary)
show_diffstat=t ;;
--sq|--squ|--squa|--squas|--squash)
allow_fast_forward=t squash=t no_commit=t ;;
--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
allow_fast_forward=t squash= no_commit= ;;
--c|--co|--com|--comm|--commi|--commit)
allow_fast_forward=t squash= no_commit= ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
allow_fast_forward=t squash= no_commit=t ;;
--ff)
allow_fast_forward=t squash= no_commit= ;;
--no-ff)
allow_fast_forward=false squash= no_commit= ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
case "$#,$1" in
*,*=*)
strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
strategy="$2"
shift ;;
esac
case " $all_strategies " in
*" $strategy "*)
use_strategies="$use_strategies$strategy " ;;
*)
die "available strategies are: $all_strategies" ;;
esac
;;
-m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
merge_msg=`expr "z$1" : 'z-[^=]*=\(.*\)'`
have_message=t
;;
-m|--m|--me|--mes|--mess|--messa|--messag|--message)
shift
case "$#" in
1) usage ;;
esac
merge_msg="$1"
have_message=t
;;
-*) usage ;;
*) return 1 ;;
esac
shift
args_left=$#
}
parse_config () {
while test $# -gt 0
do
parse_option "$@" || usage
while test $args_left -lt $#
do
while test $# != 0; do
case "$1" in
-n|--no-summary)
show_diffstat=false ;;
--summary)
show_diffstat=t ;;
--squash)
allow_fast_forward=t squash=t no_commit=t ;;
--no-squash)
allow_fast_forward=t squash= no_commit= ;;
--commit)
allow_fast_forward=t squash= no_commit= ;;
--no-commit)
allow_fast_forward=t squash= no_commit=t ;;
--ff)
allow_fast_forward=t squash= no_commit= ;;
--no-ff)
allow_fast_forward=false squash= no_commit= ;;
-s|--strategy)
shift
done
case " $all_strategies " in
*" $1 "*)
use_strategies="$use_strategies$1 " ;;
*)
die "available strategies are: $all_strategies" ;;
esac
;;
-m|--message)
shift
merge_msg="$1"
have_message=t
;;
--)
shift
break ;;
*) usage ;;
esac
shift
done
args_left=$#
}
test $# != 0 || usage
@@ -227,17 +214,12 @@ then
mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
if test -n "$mergeopts"
then
parse_config $mergeopts
parse_config $mergeopts --
fi
fi
while parse_option "$@"
do
while test $args_left -lt $#
do
shift
done
done
parse_config "$@"
while test $args_left -lt $#; do shift; done
if test -z "$show_diffstat"; then
test "$(git config --bool merge.diffstat)" = false && show_diffstat=false

View File

@@ -10,6 +10,7 @@
USAGE='[--tool=tool] [file to merge] ...'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
prefix=$(git rev-parse --show-prefix)

View File

@@ -7,6 +7,7 @@
USAGE='[-n | --no-summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
set_reflog_action "pull $*"
require_work_tree

View File

@@ -1,5 +1,12 @@
#!/bin/sh
USAGE='--dry-run --author <author> --patches </path/to/quilt/patch/directory>'
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-quiltimport [options]
--
n,dry-run dry run
author= author name and email address for patches without any
patches= path to the quilt series and patches
"
SUBDIRECTORY_ON=Yes
. git-sh-setup
@@ -8,39 +15,25 @@ quilt_author=""
while test $# != 0
do
case "$1" in
--au=*|--aut=*|--auth=*|--autho=*|--author=*)
quilt_author=$(expr "z$1" : 'z-[^=]*\(.*\)')
shift
;;
--au|--aut|--auth|--autho|--author)
case "$#" in 1) usage ;; esac
--author)
shift
quilt_author="$1"
shift
;;
--dry-run)
shift
-n|--dry-run)
dry_run=1
;;
--pa=*|--pat=*|--patc=*|--patch=*|--patche=*|--patches=*)
QUILT_PATCHES=$(expr "z$1" : 'z-[^=]*\(.*\)')
shift
;;
--pa|--pat|--patc|--patch|--patche|--patches)
case "$#" in 1) usage ;; esac
--patches)
shift
QUILT_PATCHES="$1"
shift
;;
--)
shift
break;;
*)
break
usage
;;
esac
shift
done
# Quilt Author

View File

@@ -13,6 +13,7 @@
USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
[--onto <branch>] <upstream> [<branch>])'
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
@@ -484,8 +485,13 @@ do
SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
SHORTHEAD=$(git rev-parse --short $HEAD)
SHORTONTO=$(git rev-parse --short $ONTO)
cat > "$TODO" << EOF
# Rebasing $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
--abbrev=7 --reverse --left-right --cherry-pick \
$UPSTREAM...$HEAD | \
sed -n "s/^>/pick /p" > "$TODO"
cat >> "$TODO" << EOF
# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
#
# Commands:
# pick = use commit
@@ -493,12 +499,9 @@ do
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
EOF
git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
--abbrev=7 --reverse --left-right --cherry-pick \
$UPSTREAM...$HEAD | \
sed -n "s/^>/pick /p" >> "$TODO"
has_action "$TODO" ||
die_abort "Nothing to do"

View File

@@ -29,6 +29,7 @@ Example: git-rebase master~1 topic
'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
set_reflog_action rebase
require_work_tree

View File

@@ -3,7 +3,22 @@
# Copyright (c) 2005 Linus Torvalds
#
USAGE='[-a|-A] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--window-memory=N] [--depth=N]'
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-repack [options]
--
a pack everything in a single pack
A same as -a, and keep unreachable objects too
d remove redundant packs, and run git-prune-packed
f pass --no-reuse-delta to git-pack-objects
q,quiet be quiet
l pass --local to git-pack-objects
Packing constraints
window= size of the window used for delta compression
window-memory= same as the above, but limit memory size instead of entries count
depth= limits the maximum delta depth
max-pack-size= maximum size of each packfile
"
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -20,10 +35,9 @@ do
-q) quiet=-q ;;
-f) no_reuse=--no-reuse-object ;;
-l) local=--local ;;
--max-pack-size=*) extra="$extra $1" ;;
--window=*) extra="$extra $1" ;;
--window-memory=*) extra="$extra $1" ;;
--depth=*) extra="$extra $1" ;;
--max-pack-size|--window|--window-memory|--depth)
extra="$extra $1=$2"; shift ;;
--) shift; break;;
*) usage ;;
esac
shift

View File

@@ -8,6 +8,7 @@ USAGE='<commit> <url> [<head>]'
LONG_USAGE='Summarizes the changes since <commit> to the standard output,
and includes <url> in the message generated.'
SUBDIRECTORY_OK='Yes'
OPTIONS_SPEC=
. git-sh-setup
. git-parse-remote

View File

@@ -145,6 +145,7 @@ sub format_2822_time {
my $have_email_valid = eval { require Email::Valid; 1 };
my $smtp;
my $auth;
sub unique_email_list(@);
sub cleanup_compose_files();
@@ -514,11 +515,13 @@ $time = time - scalar $#files;
sub unquote_rfc2047 {
local ($_) = @_;
if (s/=\?utf-8\?q\?(.*)\?=/$1/g) {
my $encoding;
if (s/=\?([^?]+)\?q\?(.*)\?=/$2/g) {
$encoding = $1;
s/_/ /g;
s/=([0-9A-F]{2})/chr(hex($1))/eg;
}
return "$_";
return wantarray ? ($_, $encoding) : $_;
}
# use the simplest quoting being able to handle the recipient
@@ -555,7 +558,11 @@ sub sanitize_address
sub send_message
{
my @recipients = unique_email_list(@to);
@cc = (map { sanitize_address($_) } @cc);
@cc = (grep { my $cc = extract_valid_address($_);
not grep { $cc eq $_ } @recipients
}
map { sanitize_address($_) }
@cc);
my $to = join (",\n\t", @recipients);
@recipients = unique_email_list(@recipients,@cc,@bcclist);
@recipients = (map { extract_valid_address($_) } @recipients);
@@ -629,7 +636,7 @@ X-Mailer: git-send-email $gitversion
}
if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
$smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
$auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
}
$smtp->mail( $raw_from ) or die $smtp->message;
$smtp->to( @recipients ) or die $smtp->message;
@@ -641,7 +648,7 @@ X-Mailer: git-send-email $gitversion
if ($quiet) {
printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject);
} else {
print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n");
print (($dry_run ? "Dry-" : "")."OK. Log says:\n");
if ($smtp_server !~ m#^/#) {
print "Server: $smtp_server\n";
print "MAIL FROM:<$raw_from>\n";
@@ -649,7 +656,7 @@ X-Mailer: git-send-email $gitversion
} else {
print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n";
}
print "From: $sanitized_sender\nSubject: $subject\nCc: $cc\nTo: $to\n\n";
print $header, "\n";
if ($smtp) {
print "Result: ", $smtp->code, ' ',
($smtp->message =~ /\n([^\n]+\n)$/s), "\n";
@@ -667,6 +674,9 @@ foreach my $t (@files) {
open(F,"<",$t) or die "can't open file $t";
my $author = undef;
my $author_encoding;
my $has_content_type;
my $body_encoding;
@cc = @initial_cc;
@xh = ();
my $input_format = undef;
@@ -692,12 +702,20 @@ foreach my $t (@files) {
next if ($suppress_from);
}
elsif ($1 eq 'From') {
$author = unquote_rfc2047($2);
($author, $author_encoding)
= unquote_rfc2047($2);
}
printf("(mbox) Adding cc: %s from line '%s'\n",
$2, $_) unless $quiet;
push @cc, $2;
}
elsif (/^Content-type:/i) {
$has_content_type = 1;
if (/charset="?[^ "]+/) {
$body_encoding = $1;
}
push @xh, $_;
}
elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) {
push @xh, $_;
}
@@ -756,6 +774,22 @@ foreach my $t (@files) {
if (defined $author) {
$message = "From: $author\n\n$message";
if (defined $author_encoding) {
if ($has_content_type) {
if ($body_encoding eq $author_encoding) {
# ok, we already have the right encoding
}
else {
# uh oh, we should re-encode
}
}
else {
push @xh,
'MIME-Version: 1.0',
"Content-Type: text/plain; charset=$author_encoding",
'Content-Transfer-Encoding: 8bit';
}
}
}
send_message();

View File

@@ -16,9 +16,40 @@ die() {
exit 1
}
usage() {
die "Usage: $0 $USAGE"
}
if test -n "$OPTIONS_SPEC"; then
usage() {
exec "$0" -h
}
parseopt_extra=
[ -n "$OPTIONS_KEEPDASHDASH" ] &&
parseopt_extra="--keep-dashdash"
eval "$(
echo "$OPTIONS_SPEC" |
git rev-parse --parseopt $parseopt_extra -- "$@" ||
echo exit $?
)"
else
usage() {
die "Usage: $0 $USAGE"
}
if [ -z "$LONG_USAGE" ]
then
LONG_USAGE="Usage: $0 $USAGE"
else
LONG_USAGE="Usage: $0 $USAGE
$LONG_USAGE"
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "$LONG_USAGE"
exit
esac
fi
set_reflog_action() {
if [ -z "${GIT_REFLOG_ACTION:+set}" ]
@@ -91,21 +122,6 @@ get_author_ident_from_commit () {
LANG=C LC_ALL=C sed -ne "$pick_author_script"
}
if [ -z "$LONG_USAGE" ]
then
LONG_USAGE="Usage: $0 $USAGE"
else
LONG_USAGE="Usage: $0 $USAGE
$LONG_USAGE"
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "$LONG_USAGE"
exit
esac
# Make sure we are in a valid repository of a vintage we understand.
if [ -z "$SUBDIRECTORY_OK" ]
then

View File

@@ -4,6 +4,7 @@
USAGE='[ | list | show | apply | clear]'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
cd_to_toplevel

View File

@@ -5,6 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
OPTIONS_SPEC=
. git-sh-setup
require_work_tree

View File

@@ -48,7 +48,8 @@ BEGIN {
foreach (qw/command command_oneline command_noisy command_output_pipe
command_input_pipe command_close_pipe/) {
for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
Git::SVN::Migration Git::SVN::Log Git::SVN),
Git::SVN::Migration Git::SVN::Log Git::SVN
Git::SVN::Util),
__PACKAGE__) {
*{"${package}::$_"} = \&{"Git::$_"};
}
@@ -64,7 +65,7 @@ my ($_stdin, $_help, $_edit,
$_template, $_shared,
$_version, $_fetch_all, $_no_rebase,
$_merge, $_strategy, $_dry_run, $_local,
$_prefix, $_no_checkout, $_verbose);
$_prefix, $_no_checkout, $_url, $_verbose);
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -177,6 +178,10 @@ my %cmd = (
'file|F=s' => \$_file,
'revision|r=s' => \$_revision,
%cmt_opts } ],
'info' => [ \&cmd_info,
"Show info about the latest SVN revision
on the current branch",
{ 'url' => \$_url, } ],
);
my $cmd;
@@ -391,7 +396,7 @@ sub cmd_set_tree {
sub cmd_dcommit {
my $head = shift;
git_cmd_try { command_oneline(qw/diff-index --quiet HEAD/) }
'Cannot dcommit with a dirty index. Commit your changes first'
'Cannot dcommit with a dirty index. Commit your changes first, '
. "or stash them with `git stash'.\n";
$head ||= 'HEAD';
my @refs;
@@ -425,6 +430,9 @@ sub cmd_dcommit {
my %ed_opts = ( r => $last_rev,
log => get_commit_entry($d)->{log},
ra => Git::SVN::Ra->new($gs->full_url),
config => SVN::Core::config_get_config(
$Git::SVN::Ra::config_dir
),
tree_a => "$d~1",
tree_b => $d,
editor_cb => sub {
@@ -580,6 +588,23 @@ sub cmd_create_ignore {
});
}
sub canonicalize_path {
my ($path) = @_;
my $dot_slash_added = 0;
if (substr($path, 0, 1) ne "/") {
$path = "./" . $path;
$dot_slash_added = 1;
}
# File::Spec->canonpath doesn't collapse x/../y into y (for a
# good reason), so let's do this manually.
$path =~ s#/+#/#g;
$path =~ s#/\.(?:/|$)#/#g;
$path =~ s#/[^/]+/\.\.##g;
$path =~ s#/$##g;
$path =~ s#^\./## if $dot_slash_added;
return $path;
}
# get_svnprops(PATH)
# ------------------
# Helper for cmd_propget and cmd_proplist below.
@@ -597,12 +622,7 @@ sub get_svnprops {
# canonicalize the path (otherwise libsvn will abort or fail to
# find the file)
# File::Spec->canonpath doesn't collapse x/../y into y (for a
# good reason), so let's do this manually.
$path =~ s#/+#/#g;
$path =~ s#/\.(?:/|$)#/#g;
$path =~ s#/[^/]+/\.\.##g;
$path =~ s#/$##g;
$path = canonicalize_path($path);
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
my $props;
@@ -733,6 +753,114 @@ sub cmd_commit_diff {
}
}
sub cmd_info {
my $path = canonicalize_path(shift or ".");
unless (scalar(@_) == 0) {
die "Too many arguments specified\n";
}
my ($file_type, $diff_status) = find_file_type_and_diff_status($path);
if (!$file_type && !$diff_status) {
print STDERR "$path: (Not a versioned resource)\n\n";
return;
}
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
unless ($gs) {
die "Unable to determine upstream SVN information from ",
"working tree history\n";
}
my $full_url = $url . ($path eq "." ? "" : "/$path");
if ($_url) {
print $full_url, "\n";
return;
}
my $result = "Path: $path\n";
$result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
$result .= "URL: " . $full_url . "\n";
eval {
my $repos_root = $gs->repos_root;
Git::SVN::remove_username($repos_root);
$result .= "Repository Root: $repos_root\n";
};
if ($@) {
$result .= "Repository Root: (offline)\n";
}
$result .= "Repository UUID: $uuid\n" unless $diff_status eq "A";
$result .= "Revision: " . ($diff_status eq "A" ? 0 : $rev) . "\n";
$result .= "Node Kind: " .
($file_type eq "dir" ? "directory" : "file") . "\n";
my $schedule = $diff_status eq "A"
? "add"
: ($diff_status eq "D" ? "delete" : "normal");
$result .= "Schedule: $schedule\n";
if ($diff_status eq "A") {
print $result, "\n";
return;
}
my ($lc_author, $lc_rev, $lc_date_utc);
my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path);
my $log = command_output_pipe(@args);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
if (/^${esc_color}author (.+) <[^>]+> (\d+) ([\-\+]?\d+)$/o) {
$lc_author = $1;
$lc_date_utc = Git::SVN::Log::parse_git_date($2, $3);
} elsif (/^${esc_color} (git-svn-id:.+)$/o) {
(undef, $lc_rev, undef) = ::extract_metadata($1);
}
}
close $log;
Git::SVN::Log::set_local_timezone();
$result .= "Last Changed Author: $lc_author\n";
$result .= "Last Changed Rev: $lc_rev\n";
$result .= "Last Changed Date: " .
Git::SVN::Log::format_svn_date($lc_date_utc) . "\n";
if ($file_type ne "dir") {
my $text_last_updated_date =
($diff_status eq "D" ? $lc_date_utc : (stat $path)[9]);
$result .=
"Text Last Updated: " .
Git::SVN::Log::format_svn_date($text_last_updated_date) .
"\n";
my $checksum;
if ($diff_status eq "D") {
my ($fh, $ctx) =
command_output_pipe(qw(cat-file blob), "HEAD:$path");
if ($file_type eq "link") {
my $file_name = <$fh>;
$checksum = Git::SVN::Util::md5sum("link $file_name");
} else {
$checksum = Git::SVN::Util::md5sum($fh);
}
command_close_pipe($fh, $ctx);
} elsif ($file_type eq "link") {
my $file_name =
command(qw(cat-file blob), "HEAD:$path");
$checksum =
Git::SVN::Util::md5sum("link " . $file_name);
} else {
open FILE, "<", $path or die $!;
$checksum = Git::SVN::Util::md5sum(\*FILE);
close FILE or die $!;
}
$result .= "Checksum: " . $checksum . "\n";
}
print $result, "\n";
}
########################### utility functions #########################
sub rebase_cmd {
@@ -1040,6 +1168,52 @@ sub linearize_history {
(\@linear_refs, \%parents);
}
sub find_file_type_and_diff_status {
my ($path) = @_;
return ('dir', '') if $path eq '.';
my $diff_output =
command_oneline(qw(diff --cached --name-status --), $path) || "";
my $diff_status = (split(' ', $diff_output))[0] || "";
my $ls_tree = command_oneline(qw(ls-tree HEAD), $path) || "";
return (undef, undef) if !$diff_status && !$ls_tree;
if ($diff_status eq "A") {
return ("link", $diff_status) if -l $path;
return ("dir", $diff_status) if -d $path;
return ("file", $diff_status);
}
my $mode = (split(' ', $ls_tree))[0] || "";
return ("link", $diff_status) if $mode eq "120000";
return ("dir", $diff_status) if $mode eq "040000";
return ("file", $diff_status);
}
package Git::SVN::Util;
use strict;
use warnings;
use Digest::MD5;
sub md5sum {
my $arg = shift;
my $ref = ref $arg;
my $md5 = Digest::MD5->new();
if ($ref eq 'GLOB' || $ref eq 'IO::File') {
$md5->addfile($arg) or croak $!;
} elsif ($ref eq 'SCALAR') {
$md5->add($$arg) or croak $!;
} elsif (!$ref) {
$md5->add($arg) or croak $!;
} else {
::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
}
return $md5->hexdigest();
}
package Git::SVN;
use strict;
use warnings;
@@ -1604,9 +1778,24 @@ sub ra_uuid {
$self->{ra_uuid};
}
sub _set_repos_root {
my ($self, $repos_root) = @_;
my $k = "svn-remote.$self->{repo_id}.reposRoot";
$repos_root ||= $self->ra->{repos_root};
tmp_config($k, $repos_root);
$repos_root;
}
sub repos_root {
my ($self) = @_;
my $k = "svn-remote.$self->{repo_id}.reposRoot";
eval { tmp_config('--get', $k) } || $self->_set_repos_root;
}
sub ra {
my ($self) = shift;
my $ra = Git::SVN::Ra->new($self->{url});
$self->_set_repos_root($ra->{repos_root});
if ($self->use_svm_props && !$self->{svm}) {
if ($self->no_metadata) {
die "Can't have both 'noMetadata' and ",
@@ -2396,10 +2585,15 @@ sub rev_db_get {
$ret;
}
# Finds the first svn revision that exists on (if $eq_ok is true) or
# before $rev for the current branch. It will not search any lower
# than $min_rev. Returns the git commit hash and svn revision number
# if found, else (undef, undef).
sub find_rev_before {
my ($self, $rev, $eq_ok) = @_;
my ($self, $rev, $eq_ok, $min_rev) = @_;
--$rev unless $eq_ok;
while ($rev > 0) {
$min_rev ||= 1;
while ($rev >= $min_rev) {
if (my $c = $self->rev_db_get($rev)) {
return ($rev, $c);
}
@@ -2408,6 +2602,23 @@ sub find_rev_before {
return (undef, undef);
}
# Finds the first svn revision that exists on (if $eq_ok is true) or
# after $rev for the current branch. It will not search any higher
# than $max_rev. Returns the git commit hash and svn revision number
# if found, else (undef, undef).
sub find_rev_after {
my ($self, $rev, $eq_ok, $max_rev) = @_;
++$rev unless $eq_ok;
$max_rev ||= $self->rev_db_max();
while ($rev <= $max_rev) {
if (my $c = $self->rev_db_get($rev)) {
return ($rev, $c);
}
++$rev;
}
return (undef, undef);
}
sub _new {
my ($class, $repo_id, $ref_id, $path) = @_;
unless (defined $repo_id && length $repo_id) {
@@ -2585,7 +2796,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File qw//;
use Digest::MD5;
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
sub new {
@@ -2737,9 +2947,7 @@ sub apply_textdelta {
if (defined $exp) {
seek $base, 0, 0 or croak $!;
my $md5 = Digest::MD5->new;
$md5->addfile($base);
my $got = $md5->hexdigest;
my $got = Git::SVN::Util::md5sum($base);
die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
"expected: $exp\n",
" got: $got\n" if ($got ne $exp);
@@ -2758,9 +2966,7 @@ sub close_file {
if (my $fh = $fb->{fh}) {
if (defined $exp) {
seek($fh, 0, 0) or croak $!;
my $md5 = Digest::MD5->new;
$md5->addfile($fh);
my $got = $md5->hexdigest;
my $got = Git::SVN::Util::md5sum($fh);
if ($got ne $exp) {
die "Checksum mismatch: $path\n",
"expected: $exp\n got: $got\n";
@@ -2812,7 +3018,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File;
use Digest::MD5;
sub new {
my ($class, $opts) = @_;
@@ -3116,11 +3321,9 @@ sub chg_file {
$fh->flush == 0 or croak $!;
seek $fh, 0, 0 or croak $!;
my $md5 = Digest::MD5->new;
$md5->addfile($fh) or croak $!;
my $exp = Git::SVN::Util::md5sum($fh);
seek $fh, 0, 0 or croak $!;
my $exp = $md5->hexdigest;
my $pool = SVN::Pool->new;
my $atd = $self->apply_textdelta($fbat, undef, $pool);
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
@@ -3698,6 +3901,7 @@ package Git::SVN::Log;
use strict;
use warnings;
use POSIX qw/strftime/;
use constant commit_log_separator => ('-' x 72) . "\n";
use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
%rusers $show_commit $incremental/;
my $l_fmt;
@@ -3791,19 +3995,19 @@ sub git_svn_log_cmd {
push @cmd, $c;
}
} elsif (defined $r_max) {
my ($c_min, $c_max);
$c_max = $gs->rev_db_get($r_max);
$c_min = $gs->rev_db_get($r_min);
if (defined $c_min && defined $c_max) {
if ($r_max > $r_max) {
push @cmd, "$c_min..$c_max";
} else {
push @cmd, "$c_max..$c_min";
}
} elsif ($r_max > $r_min) {
push @cmd, $c_max;
if ($r_max < $r_min) {
($r_min, $r_max) = ($r_max, $r_min);
}
my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
# If there are no commits in the range, both $c_max and $c_min
# will be undefined. If there is at least 1 commit in the
# range, both will be defined.
return () if !defined $c_min || !defined $c_max;
if ($c_min eq $c_max) {
push @cmd, '--max-count=1', $c_min;
} else {
push @cmd, $c_min;
push @cmd, '--boundary', "$c_min..$c_max";
}
}
return (@cmd, @files);
@@ -3833,6 +4037,29 @@ sub run_pager {
exec $pager or ::fatal "Can't run pager: $! ($pager)";
}
sub format_svn_date {
return strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)", localtime(shift));
}
sub parse_git_date {
my ($t, $tz) = @_;
# Date::Parse isn't in the standard Perl distro :(
if ($tz =~ s/^\+//) {
$t += tz_to_s_offset($tz);
} elsif ($tz =~ s/^\-//) {
$t -= tz_to_s_offset($tz);
}
return $t;
}
sub set_local_timezone {
if (defined $TZ) {
$ENV{TZ} = $TZ;
} else {
delete $ENV{TZ};
}
}
sub tz_to_s_offset {
my ($tz) = @_;
$tz =~ s/(\d\d)$//;
@@ -3853,13 +4080,7 @@ sub get_author_info {
$dest->{t} = $t;
$dest->{tz} = $tz;
$dest->{a} = $au;
# Date::Parse isn't in the standard Perl distro :(
if ($tz =~ s/^\+//) {
$t += tz_to_s_offset($tz);
} elsif ($tz =~ s/^\-//) {
$t -= tz_to_s_offset($tz);
}
$dest->{t_utc} = $t;
$dest->{t_utc} = parse_git_date($t, $tz);
}
sub process_commit {
@@ -3911,10 +4132,9 @@ sub show_commit_changed_paths {
sub show_commit_normal {
my ($c) = @_;
print '-' x72, "\nr$c->{r} | ";
print commit_log_separator, "r$c->{r} | ";
print "$c->{c} | " if $show_commit;
print "$c->{a} | ", strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)",
localtime($c->{t_utc})), ' | ';
print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
my $nr_line = 0;
if (my $l = $c->{l}) {
@@ -3954,11 +4174,7 @@ sub cmd_show_log {
my (@args) = @_;
my ($r_min, $r_max);
my $r_last = -1; # prevent dupes
if (defined $TZ) {
$ENV{TZ} = $TZ;
} else {
delete $ENV{TZ};
}
set_local_timezone();
if (defined $::_revision) {
if ($::_revision =~ /^(\d+):(\d+)$/) {
($r_min, $r_max) = ($1, $2);
@@ -3972,12 +4188,16 @@ sub cmd_show_log {
config_pager();
@args = git_svn_log_cmd($r_min, $r_max, @args);
if (!@args) {
print commit_log_separator unless $incremental || $oneline;
return;
}
my $log = command_output_pipe(@args);
run_pager();
my (@k, $c, $d, $stat);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
if (/^${esc_color}commit ($::sha1_short)/o) {
if (/^${esc_color}commit -?($::sha1_short)/o) {
my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r};
@@ -4020,14 +4240,12 @@ sub cmd_show_log {
process_commit($c, $r_min, $r_max, \@k);
}
if (@k) {
my $swap = $r_max;
$r_max = $r_min;
$r_min = $swap;
($r_min, $r_max) = ($r_max, $r_min);
process_commit($_, $r_min, $r_max) foreach reverse @k;
}
out:
close $log;
print '-' x72,"\n" unless $incremental || $oneline;
print commit_log_separator unless $incremental || $oneline;
}
package Git::SVN::Migration;

3
git.c
View File

@@ -325,6 +325,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "mailsplit", cmd_mailsplit },
{ "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file },
{ "merge-ours", cmd_merge_ours, RUN_SETUP },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
@@ -338,7 +339,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "rerere", cmd_rerere, RUN_SETUP },
{ "reset", cmd_reset, RUN_SETUP },
{ "rev-list", cmd_rev_list, RUN_SETUP },
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "rev-parse", cmd_rev_parse },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP },
{ "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },

View File

@@ -85,6 +85,10 @@ div.title, a.title {
color: #000000;
}
div.readme {
padding: 8px;
}
a.title:hover {
background-color: #d9d8d1;
}
@@ -170,14 +174,10 @@ a.text:hover {
table {
padding: 8px 4px;
}
table.project_list {
border-spacing: 0;
}
table.diff_tree {
border-spacing: 0;
font-family: monospace;
}

View File

@@ -3544,7 +3544,7 @@ sub git_shortlog_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
print "<table class=\"shortlog\" cellspacing=\"0\">\n";
print "<table class=\"shortlog\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3590,7 +3590,7 @@ sub git_history_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist});
print "<table class=\"history\" cellspacing=\"0\">\n";
print "<table class=\"history\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3650,7 +3650,7 @@ sub git_tags_body {
$from = 0 unless defined $from;
$to = $#{$taglist} if (!defined $to || $#{$taglist} < $to);
print "<table class=\"tags\" cellspacing=\"0\">\n";
print "<table class=\"tags\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $taglist->[$i];
@@ -3713,7 +3713,7 @@ sub git_heads_body {
$from = 0 unless defined $from;
$to = $#{$headlist} if (!defined $to || $#{$headlist} < $to);
print "<table class=\"heads\" cellspacing=\"0\">\n";
print "<table class=\"heads\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $headlist->[$i];
@@ -3750,7 +3750,7 @@ sub git_search_grep_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
print "<table class=\"grep\" cellspacing=\"0\">\n";
print "<table class=\"commit_search\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3891,7 +3891,7 @@ sub git_summary {
git_print_page_nav('summary','', $head);
print "<div class=\"title\">&nbsp;</div>\n";
print "<table cellspacing=\"0\">\n" .
print "<table class=\"projects_list\">\n" .
"<tr><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
"<tr><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
if (defined $cd{'rfc2822'}) {
@@ -3912,8 +3912,10 @@ sub git_summary {
if (-s "$projectroot/$project/README.html") {
if (open my $fd, "$projectroot/$project/README.html") {
print "<div class=\"title\">readme</div>\n";
print "<div class=\"title\">readme</div>\n" .
"<div class=\"readme\">\n";
print $_ while (<$fd>);
print "\n</div>\n"; # class="readme"
close $fd;
}
}
@@ -3965,7 +3967,7 @@ sub git_tag {
git_print_header_div('commit', esc_html($tag{'name'}), $hash);
print "<div class=\"title_text\">\n" .
"<table cellspacing=\"0\">\n" .
"<table class=\"object_header\">\n" .
"<tr>\n" .
"<td>object</td>\n" .
"<td>" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
@@ -4405,7 +4407,7 @@ sub git_tree {
}
git_print_page_path($file_name, 'tree', $hash_base);
print "<div class=\"page_body\">\n";
print "<table cellspacing=\"0\">\n";
print "<table class=\"tree\">\n";
my $alternate = 1;
# '..' (top directory) link if possible
if (defined $hash_base &&
@@ -4627,7 +4629,7 @@ sub git_commit {
git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);
}
print "<div class=\"title_text\">\n" .
"<table cellspacing=\"0\">\n";
"<table class=\"object_header\">\n";
print "<tr><td>author</td><td>" . esc_html($co{'author'}) . "</td></tr>\n".
"<tr>" .
"<td></td><td> $ad{'rfc2822'}";
@@ -5226,7 +5228,7 @@ sub git_search {
git_print_page_nav('','', $hash,$co{'tree'},$hash);
git_print_header_div('commit', esc_html($co{'title'}), $hash);
print "<table cellspacing=\"0\">\n";
print "<table class=\"pickaxe search\">\n";
my $alternate = 1;
$/ = "\n";
my $git_command = git_cmd_str();
@@ -5293,7 +5295,7 @@ sub git_search {
git_print_page_nav('','', $hash,$co{'tree'},$hash);
git_print_header_div('commit', esc_html($co{'title'}), $hash);
print "<table cellspacing=\"0\">\n";
print "<table class=\"grep_search\">\n";
my $alternate = 1;
my $matches = 0;
$/ = "\n";

View File

@@ -245,8 +245,7 @@ void show_log(struct rev_info *opt, const char *sep)
opt->diffopt.stat_sep = buffer;
}
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT),
stdout);
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
fputs("commit ", stdout);
if (commit->object.flags & BOUNDARY)
@@ -266,8 +265,7 @@ void show_log(struct rev_info *opt, const char *sep)
diff_unique_abbrev(parent->object.sha1,
abbrev_commit));
show_decorations(commit);
printf("%s",
diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
if (opt->reflog_info) {
show_reflog_message(opt->reflog_info,

View File

@@ -366,7 +366,7 @@ static struct path_list *get_renames(struct tree *tree,
renames = xcalloc(1, sizeof(struct path_list));
diff_setup(&opts);
opts.recursive = 1;
DIFF_OPT_SET(&opts, RECURSIVE);
opts.detect_rename = DIFF_DETECT_RENAME;
opts.rename_limit = rename_limit;
opts.output_format = DIFF_FORMAT_NO_OUTPUT;

View File

@@ -40,24 +40,53 @@ static int get_value(struct optparse_t *p,
const struct option *opt, int flags)
{
const char *s, *arg;
arg = p->opt ? p->opt : (p->argc > 1 ? p->argv[1] : NULL);
const int unset = flags & OPT_UNSET;
if (p->opt && (flags & OPT_UNSET))
if (unset && p->opt)
return opterror(opt, "takes no value", flags);
if (unset && (opt->flags & PARSE_OPT_NONEG))
return opterror(opt, "isn't available", flags);
switch (opt->type) {
case OPTION_BOOLEAN:
if (!(flags & OPT_SHORT) && p->opt)
if (!(flags & OPT_SHORT) && p->opt) {
switch (opt->type) {
case OPTION_CALLBACK:
if (!(opt->flags & PARSE_OPT_NOARG))
break;
/* FALLTHROUGH */
case OPTION_BOOLEAN:
case OPTION_BIT:
case OPTION_SET_INT:
case OPTION_SET_PTR:
return opterror(opt, "takes no value", flags);
if (flags & OPT_UNSET)
*(int *)opt->value = 0;
default:
break;
}
}
arg = p->opt ? p->opt : (p->argc > 1 ? p->argv[1] : NULL);
switch (opt->type) {
case OPTION_BIT:
if (unset)
*(int *)opt->value &= ~opt->defval;
else
(*(int *)opt->value)++;
*(int *)opt->value |= opt->defval;
return 0;
case OPTION_BOOLEAN:
*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
return 0;
case OPTION_SET_INT:
*(int *)opt->value = unset ? 0 : opt->defval;
return 0;
case OPTION_SET_PTR:
*(void **)opt->value = unset ? NULL : (void *)opt->defval;
return 0;
case OPTION_STRING:
if (flags & OPT_UNSET) {
*(const char **)opt->value = (const char *)NULL;
if (unset) {
*(const char **)opt->value = NULL;
return 0;
}
if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) {
@@ -70,13 +99,10 @@ static int get_value(struct optparse_t *p,
return 0;
case OPTION_CALLBACK:
if (flags & OPT_UNSET)
if (unset)
return (*opt->callback)(opt, NULL, 1);
if (opt->flags & PARSE_OPT_NOARG) {
if (p->opt && !(flags & OPT_SHORT))
return opterror(opt, "takes no value", flags);
if (opt->flags & PARSE_OPT_NOARG)
return (*opt->callback)(opt, NULL, 0);
}
if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-'))
return (*opt->callback)(opt, NULL, 0);
if (!arg)
@@ -84,7 +110,7 @@ static int get_value(struct optparse_t *p,
return (*opt->callback)(opt, get_arg(p), 0);
case OPTION_INTEGER:
if (flags & OPT_UNSET) {
if (unset) {
*(int *)opt->value = 0;
return 0;
}
@@ -292,7 +318,7 @@ void usage_with_options(const char * const *usagestr,
pos += fprintf(stderr, " ...");
}
break;
default:
default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */
break;
}
@@ -311,6 +337,7 @@ void usage_with_options(const char * const *usagestr,
/*----- some often used options -----*/
#include "cache.h"
int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
{
int v;

View File

@@ -2,9 +2,15 @@
#define PARSE_OPTIONS_H
enum parse_opt_type {
/* special types */
OPTION_END,
OPTION_GROUP,
OPTION_BOOLEAN,
/* options with no arguments */
OPTION_BIT,
OPTION_BOOLEAN, /* _INCR would have been a better name */
OPTION_SET_INT,
OPTION_SET_PTR,
/* options with arguments (usually) */
OPTION_STRING,
OPTION_INTEGER,
OPTION_CALLBACK,
@@ -17,6 +23,7 @@ enum parse_opt_flags {
enum parse_opt_option_flags {
PARSE_OPT_OPTARG = 1,
PARSE_OPT_NOARG = 2,
PARSE_OPT_NONEG = 4,
};
struct option;
@@ -49,12 +56,15 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
* mask of parse_opt_option_flags.
* PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
* PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
* PARSE_OPT_NONEG: says that this option cannot be negated
*
* `callback`::
* pointer to the callback to use for OPTION_CALLBACK.
*
* `defval`::
* default value to fill (*->value) with for PARSE_OPT_OPTARG.
* OPTION_{BIT,SET_INT,SET_PTR} store the {mask,integer,pointer} to put in
* the value when met.
* CALLBACKS can use it like they want.
*/
struct option {
@@ -72,7 +82,10 @@ struct option {
#define OPT_END() { OPTION_END }
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) }
#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }
#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
#define OPT_CALLBACK(s, l, v, a, h, f) \

View File

@@ -121,7 +121,7 @@ int init_patch_ids(struct patch_ids *ids)
{
memset(ids, 0, sizeof(*ids));
diff_setup(&ids->diffopts);
ids->diffopts.recursive = 1;
DIFF_OPT_SET(&ids->diffopts, RECURSIVE);
if (diff_setup_done(&ids->diffopts) < 0)
return error("diff_setup_done failed");
return 0;

View File

@@ -98,11 +98,13 @@ static int display(struct progress *progress, unsigned n, const char *done)
fprintf(stderr, "%s: %3u%% (%u/%u)%s%s",
progress->title, percent, n,
progress->total, tp, eol);
fflush(stderr);
progress_update = 0;
return 1;
}
} else if (progress_update) {
fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol);
fflush(stderr);
progress_update = 0;
return 1;
}
@@ -207,6 +209,7 @@ struct progress *start_progress_delay(const char *title, unsigned total,
if (!progress) {
/* unlikely, but here's a good fallback */
fprintf(stderr, "%s...\n", title);
fflush(stderr);
return NULL;
}
progress->title = title;

12
refs.c
View File

@@ -580,18 +580,6 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data)
return do_for_each_ref("refs/remotes/", fn, 13, cb_data);
}
/* NEEDSWORK: This is only used by ssh-upload and it should go; the
* caller should do resolve_ref or read_ref like everybody else. Or
* maybe everybody else should use get_ref_sha1() instead of doing
* read_ref().
*/
int get_ref_sha1(const char *ref, unsigned char *sha1)
{
if (check_ref_format(ref))
return -1;
return read_ref(mkpath("refs/%s", ref), sha1);
}
/*
* Make sure "ref" is something reasonable to have under ".git/refs/";
* We do not like it if:

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