Merge branch 'master' of git://repo.or.cz/alt-git

This commit is contained in:
Johannes Sixt
2008-01-21 08:27:51 +01:00
77 changed files with 3215 additions and 763 deletions

View File

@@ -23,7 +23,7 @@ ARTICLES += everyday
ARTICLES += git-tools
ARTICLES += glossary
# with their own formatting rules.
SP_ARTICLES = howto/revert-branch-rebase user-manual
SP_ARTICLES = howto/revert-branch-rebase howto/using-merge-subtree user-manual
API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
SP_ARTICLES += $(API_DOCS)
SP_ARTICLES += technical/api-index

View File

@@ -10,6 +10,9 @@ Removal
* As git-commit and git-status have been rewritten, "git runstatus"
helper script lost all its users and has been removed.
* Curl library older than 7.10 is not supported by "git http-push",
as it does not work without CURLM.
Deprecation notices
-------------------
@@ -46,6 +49,10 @@ Deprecation notices
and works for all transports; "git peek-remote" will be removed in
the future.
* "git repo-config" which was an old name for "git config" command
has been supported without being advertised for a long time. The
next feature release will remove it.
* From v1.6.0, the repack.usedeltabaseoffset config option will default
to true, which will give denser packfiles (i.e. more efficient storage).
The downside is that git older than version 1.4.4 will not be able
@@ -356,8 +363,10 @@ series.
* Recent versions of AsciiDoc 8 has a change to break our
documentation; a workaround has been implemented.
* "git diff --color-words" colored context lines in a wrong color.
--
exec >/var/tmp/1
O=v1.5.4-rc3
O=v1.5.4-rc4
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint

View File

@@ -543,8 +543,8 @@ rerere.enabled::
Activate recording of resolved conflicts, so that identical
conflict hunks can be resolved automatically, should they
be encountered again. linkgit:git-rerere[1] command is by
default enabled, but can be disabled by setting this option to
false.
default enabled if you create `rr-cache` directory under
`$GIT_DIR`, but can be disabled by setting this option to false.
gitcvs.enabled::
Whether the CVS server interface is enabled for this repository.

View File

@@ -578,7 +578,7 @@ particular state. You can, for example, do
$ git diff my-first-tag
----------------
to diff your current state against that tag (which at this point will
to diff your current state against that tag which at this point will
obviously be an empty diff, but if you continue to develop and commit
stuff, you can use your tag as an "anchor-point" to see what has changed
since you tagged it.

View File

@@ -24,7 +24,7 @@ OPTIONS
-e|--edit::
With this option, `git-cherry-pick` will let you edit the commit
message prior committing.
message prior to committing.
-x::
When recording the commit, append to the original commit

View File

@@ -19,14 +19,10 @@ command to control what is shown and how, and options applicable to
the linkgit:git-diff-tree[1] commands to control how the changes
each commit introduces are shown.
This manual page describes only the most frequently used options.
OPTIONS
-------
include::pretty-options.txt[]
:git-log: 1
include::diff-options.txt[]
@@ -41,21 +37,6 @@ include::diff-options.txt[]
and <until>, see "SPECIFYING REVISIONS" section in
linkgit:git-rev-parse[1].
--first-parent::
Follow only the first parent commit upon seeing a merge
commit. This option can give a better overview when
viewing the evolution of a particular topic branch,
because merges into a topic branch tend to be only about
adjusting to updated upstream from time to time, and
this option allows you to ignore the individual commits
brought in to your history by such a merge.
-g, \--walk-reflogs::
Show commits as they were recorded in the reflog. The log contains
a record about how the tip of a reference was changed.
Cannot be combined with --reverse.
See also linkgit:git-reflog[1].
--decorate::
Print out the ref names of any commits that are shown.
@@ -80,6 +61,8 @@ include::diff-options.txt[]
Show only commits that affect the specified paths.
include::rev-list-options.txt[]
include::pretty-formats.txt[]
include::diff-generate-patch.txt[]

View File

@@ -74,14 +74,14 @@ it happens. In other words, `git-diff --cached HEAD` must
report no changes.
[NOTE]
This is a bit of lie. In certain special cases, your index are
allowed to be different from the tree of `HEAD` commit. The most
This is a bit of a lie. In certain special cases, your index is
allowed to be different from the tree of the `HEAD` commit. The most
notable case is when your `HEAD` commit is already ahead of what
is being merged, in which case your index can have arbitrary
difference from your `HEAD` commit. Otherwise, your index entries
are allowed have differences from your `HEAD` commit that match
the result of trivial merge (e.g. you received the same patch
from external source to produce the same result as what you are
differences from your `HEAD` commit. Also, your index entries
may have differences from your `HEAD` commit that match
the result of a trivial merge (e.g. you received the same patch
from an external source to produce the same result as what you are
merging). For example, if a path did not exist in the common
ancestor and your head commit but exists in the tree you are
merging into your repository, and if you already happen to have

View File

@@ -22,6 +22,10 @@ automerge results and corresponding hand-resolve results on the
initial manual merge, and later by noticing the same automerge
results and applying the previously recorded hand resolution.
[NOTE]
You need to set the configuration variable rerere.enabled to
enable this command.
COMMANDS
--------

View File

@@ -88,363 +88,8 @@ linkgit:git-repack[1].
OPTIONS
-------
Commit Formatting
~~~~~~~~~~~~~~~~~
Using these options, linkgit:git-rev-list[1] will act similar to the
more specialized family of commit log tools: linkgit:git-log[1],
linkgit:git-show[1], and linkgit:git-whatchanged[1]
include::pretty-options.txt[]
--relative-date::
Synonym for `--date=relative`.
--date={relative,local,default,iso,rfc}::
Only takes effect for dates shown in human-readable format, such
as when using "--pretty".
+
`--date=relative` shows dates relative to the current time,
e.g. "2 hours ago".
+
`--date=local` shows timestamps in user's local timezone.
+
`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
+
`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
format, often found in E-mail messages.
+
`--date=short` shows only date but not time, in `YYYY-MM-DD` format.
+
`--date=default` shows timestamps in the original timezone
(either committer's or author's).
--header::
Print the contents of the commit in raw-format; each record is
separated with a NUL character.
--parents::
Print the parents of the commit.
--timestamp::
Print the raw commit timestamp.
--left-right::
Mark which side of a symmetric diff a commit is reachable from.
Commits from the left side are prefixed with `<` and those from
the right with `>`. If combined with `--boundary`, those
commits are prefixed with `-`.
+
For example, if you have this topology:
+
-----------------------------------------------------------------------
y---b---b branch B
/ \ /
/ .
/ / \
o---x---a---a branch A
-----------------------------------------------------------------------
+
you would get an output line this:
+
-----------------------------------------------------------------------
$ git rev-list --left-right --boundary --pretty=oneline A...B
>bbbbbbb... 3rd on b
>bbbbbbb... 2nd on b
<aaaaaaa... 3rd on a
<aaaaaaa... 2nd on a
-yyyyyyy... 1st on b
-xxxxxxx... 1st on a
-----------------------------------------------------------------------
Diff Formatting
~~~~~~~~~~~~~~~
Below are listed options that control the formatting of diff output.
Some of them are specific to linkgit:git-rev-list[1], however other diff
options may be given. See linkgit:git-diff-files[1] for more options.
-c::
This flag changes the way a merge commit is displayed. It shows
the differences from each of the parents to the merge result
simultaneously instead of showing pairwise diff between a parent
and the result one at a time. Furthermore, it lists only files
which were modified from all parents.
--cc::
This flag implies the '-c' options and further compresses the
patch output by omitting hunks that show differences from only
one parent, or show the same change from all but one parent for
an Octopus merge.
-r::
Show recursive diffs.
-t::
Show the tree objects in the diff output. This implies '-r'.
Commit Limiting
~~~~~~~~~~~~~~~
Besides specifying a range of commits that should be listed using the
special notations explained in the description, additional commit
limiting may be applied.
--
-n 'number', --max-count='number'::
Limit the number of commits output.
--skip='number'::
Skip 'number' commits before starting to show the commit output.
--since='date', --after='date'::
Show commits more recent than a specific date.
--until='date', --before='date'::
Show commits older than a specific date.
--max-age='timestamp', --min-age='timestamp'::
Limit the commits output to specified time range.
--author='pattern', --committer='pattern'::
Limit the commits output to ones with author/committer
header lines that match the specified pattern (regular expression).
--grep='pattern'::
Limit the commits output to ones with log message that
matches the specified pattern (regular expression).
-i, --regexp-ignore-case::
Match the regexp limiting patterns without regard to letters case.
-E, --extended-regexp::
Consider the limiting patterns to be extended regular expressions
instead of the default basic regular expressions.
--remove-empty::
Stop when a given path disappears from the tree.
--full-history::
Show also parts of history irrelevant to current state of a given
path. This turns off history simplification, which removed merges
which didn't change anything at all at some child. It will still actually
simplify away merges that didn't change anything at all into either
child.
--no-merges::
Do not print commits with more than one parent.
--first-parent::
Follow only the first parent commit upon seeing a merge
commit. This option can give a better overview when
viewing the evolution of a particular topic branch,
because merges into a topic branch tend to be only about
adjusting to updated upstream from time to time, and
this option allows you to ignore the individual commits
brought in to your history by such a merge.
--not::
Reverses the meaning of the '{caret}' prefix (or lack thereof)
for all following revision specifiers, up to the next '--not'.
--all::
Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the
command line as '<commit>'.
--stdin::
In addition to the '<commit>' listed on the command
line, read them from the standard input.
--quiet::
Don't print anything to standard output. This form of
git-rev-list is primarily meant to allow the caller to
test the exit status to see if a range of objects is fully
connected (or not). It is faster than redirecting stdout
to /dev/null as the output does not have to be formatted.
--cherry-pick::
Omit any commit that introduces the same change as
another commit on the "other side" when the set of
commits are limited with symmetric difference.
+
For example, if you have two branches, `A` and `B`, a usual way
to list all commits on only one side of them is with
`--left-right`, like the example above in the description of
that option. It however shows the commits that were cherry-picked
from the other branch (for example, "3rd on b" may be cherry-picked
from branch A). With this option, such pairs of commits are
excluded from the output.
-g, --walk-reflogs::
Instead of walking the commit ancestry chain, walk
reflog entries from the most recent one to older ones.
When this option is used you cannot specify commits to
exclude (that is, '{caret}commit', 'commit1..commit2',
nor 'commit1...commit2' notations cannot be used).
+
With '\--pretty' format other than oneline (for obvious reasons),
this causes the output to have two extra lines of information
taken from the reflog. By default, 'commit@\{Nth}' notation is
used in the output. When the starting commit is specified as
'commit@{now}', output also uses 'commit@\{timestamp}' notation
instead. Under '\--pretty=oneline', the commit message is
prefixed with this information on the same line.
Cannot be combined with '\--reverse'.
--merge::
After a failed merge, show refs that touch files having a
conflict and don't exist on all heads to merge.
--boundary::
Output uninteresting commits at the boundary, which are usually
not shown.
--dense, --sparse::
When optional paths are given, the default behaviour ('--dense') is to
only output commits that changes at least one of them, and also ignore
merges that do not touch the given paths.
Use the '--sparse' flag to makes the command output all eligible commits
(still subject to count and age limitation), but apply merge
simplification nevertheless.
--bisect::
Limit output to the one commit object which is roughly halfway between
the included and excluded commits. Thus, if
-----------------------------------------------------------------------
$ git-rev-list --bisect foo ^bar ^baz
-----------------------------------------------------------------------
outputs 'midpoint', the output of the two commands
-----------------------------------------------------------------------
$ git-rev-list foo ^midpoint
$ git-rev-list midpoint ^bar ^baz
-----------------------------------------------------------------------
would be of roughly the same length. Finding the change which
introduces a regression is thus reduced to a binary search: repeatedly
generate and test new 'midpoint's until the commit chain is of length
one.
--bisect-vars::
This calculates the same as `--bisect`, but outputs text ready
to be eval'ed by the shell. These lines will assign the name of
the midpoint revision to the variable `bisect_rev`, and the
expected number of commits to be tested after `bisect_rev` is
tested to `bisect_nr`, the expected number of commits to be
tested if `bisect_rev` turns out to be good to `bisect_good`,
the expected number of commits to be tested if `bisect_rev`
turns out to be bad to `bisect_bad`, and the number of commits
we are bisecting right now to `bisect_all`.
--bisect-all::
This outputs all the commit objects between the included and excluded
commits, ordered by their distance to the included and excluded
commits. The farthest from them is displayed first. (This is the only
one displayed by `--bisect`.)
This is useful because it makes it easy to choose a good commit to
test when you want to avoid to test some of them for some reason (they
may not compile for example).
This option can be used along with `--bisect-vars`, in this case,
after all the sorted commit objects, there will be the same text as if
`--bisect-vars` had been used alone.
--
Commit Ordering
~~~~~~~~~~~~~~~
By default, the commits are shown in reverse chronological order.
--topo-order::
This option makes them appear in topological order (i.e.
descendant commits are shown before their parents).
--date-order::
This option is similar to '--topo-order' in the sense that no
parent comes before all of its children, but otherwise things
are still ordered in the commit timestamp order.
--reverse::
Output the commits in reverse order.
Cannot be combined with '\--walk-reflogs'.
Object Traversal
~~~~~~~~~~~~~~~~
These options are mostly targeted for packing of git repositories.
--objects::
Print the object IDs of any object referenced by the listed
commits. 'git-rev-list --objects foo ^bar' thus means "send me
all object IDs which I need to download if I have the commit
object 'bar', but not 'foo'".
--objects-edge::
Similar to '--objects', but also print the IDs of excluded
commits prefixed with a "-" character. This is used by
linkgit:git-pack-objects[1] to build "thin" pack, which records
objects in deltified form based on objects contained in these
excluded commits to reduce network traffic.
--unpacked::
Only useful with '--objects'; print the object IDs that are not
in packs.
--no-walk::
Only show the given revs, but do not traverse their ancestors.
--do-walk::
Overrides a previous --no-walk.
:git-rev-list: 1
include::rev-list-options.txt[]
include::pretty-formats.txt[]

View File

@@ -24,7 +24,7 @@ OPTIONS
-e|--edit::
With this option, `git-revert` will let you edit the commit
message prior committing the revert. This is the default if
message prior to committing the revert. This is the default if
you run the command from a terminal.
-m parent-number|--mainline parent-number::

View File

@@ -0,0 +1,75 @@
Date: Sat, 5 Jan 2008 20:17:40 -0500
From: Sean <seanlkml@sympatico.ca>
To: Miklos Vajna <vmiklos@frugalware.org>
Cc: git@vger.kernel.org
Subject: how to use git merge -s subtree?
Abstract: In this article, Sean demonstrates how one can use the subtree merge
strategy.
Content-type: text/asciidoc
Message-ID: <BAYC1-PASMTP12374B54BA370A1E1C6E78AE4E0@CEZ.ICE>
How to use the subtree merge strategy
=====================================
There are situations where you want to include contents in your project
from an independently developed project. You can just pull from the
other project as long as there are no conflicting paths.
The problematic case is when there are conflicting files. Potential
candidates are Makefiles and other standard filenames. You could merge
these files but probably you do not want to. A better solution for this
problem can be to merge the project as its own subdirectory. This is not
supported by the 'recursive' merge strategy, so just pulling won't work.
What you want is the 'subtree' merge strategy, which helps you in such a
situation.
In this example, let's say you have the repository at `/path/to/B` (but
it can be an URL as well, if you want). You want to merge the 'master'
branch of that repository to the `dir-B` subdirectory in your current
branch.
Here is the command sequence you need:
----------------
$ git remote add -f Bproject /path/to/B <1>
$ git merge -s ours --no-commit Bproject/master <2>
$ git read-tree --prefix=dir-B/ -u Bproject/master <3>
$ git commit -m "Merge B project as our subdirectory" <4>
$ git pull -s subtree Bproject master <5>
----------------
<1> name the other project "Bproject", and fetch.
<2> prepare for the later step to record the result as a merge.
<3> read "master" branch of Bproject to the subdirectory "dir-B".
<4> record the merge result.
<5> maintain the result with subsequent merges using "subtree"
The first four commands are used for the initial merge, while the last
one is to merge updates from 'B project'.
Comparing 'subtree' merge with submodules
-----------------------------------------
- The benefit of using subtree merge is that it requires less
administrative burden from the users of your repository. It works with
older (before Git v1.5.2) clients and you have the code right after
clone.
- However if you use submodules then you can choose not to transfer the
submodule objects. This may be a problem with the subtree merge.
- Also, in case you make changes to the other project, it is easier to
submit changes if you just use submodules.
Additional tips
---------------
- If you made changes to the other project in your repository, they may
want to merge from your project. This is possible using subtree -- it
can shift up the paths in your tree and then they can merge only the
relevant parts of your tree.
- Please note that if the other project merges from you, then it will
connects its history to yours, which can be something they don't want
to.

View File

@@ -0,0 +1,361 @@
Commit Formatting
~~~~~~~~~~~~~~~~~
ifdef::git-rev-list[]
Using these options, linkgit:git-rev-list[1] will act similar to the
more specialized family of commit log tools: linkgit:git-log[1],
linkgit:git-show[1], and linkgit:git-whatchanged[1]
endif::git-rev-list[]
include::pretty-options.txt[]
--relative-date::
Synonym for `--date=relative`.
--date={relative,local,default,iso,rfc}::
Only takes effect for dates shown in human-readable format, such
as when using "--pretty".
+
`--date=relative` shows dates relative to the current time,
e.g. "2 hours ago".
+
`--date=local` shows timestamps in user's local timezone.
+
`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
+
`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
format, often found in E-mail messages.
+
`--date=short` shows only date but not time, in `YYYY-MM-DD` format.
+
`--date=default` shows timestamps in the original timezone
(either committer's or author's).
--header::
Print the contents of the commit in raw-format; each record is
separated with a NUL character.
--parents::
Print the parents of the commit.
--timestamp::
Print the raw commit timestamp.
--left-right::
Mark which side of a symmetric diff a commit is reachable from.
Commits from the left side are prefixed with `<` and those from
the right with `>`. If combined with `--boundary`, those
commits are prefixed with `-`.
+
For example, if you have this topology:
+
-----------------------------------------------------------------------
y---b---b branch B
/ \ /
/ .
/ / \
o---x---a---a branch A
-----------------------------------------------------------------------
+
you would get an output line this:
+
-----------------------------------------------------------------------
$ git rev-list --left-right --boundary --pretty=oneline A...B
>bbbbbbb... 3rd on b
>bbbbbbb... 2nd on b
<aaaaaaa... 3rd on a
<aaaaaaa... 2nd on a
-yyyyyyy... 1st on b
-xxxxxxx... 1st on a
-----------------------------------------------------------------------
Diff Formatting
~~~~~~~~~~~~~~~
Below are listed options that control the formatting of diff output.
Some of them are specific to linkgit:git-rev-list[1], however other diff
options may be given. See linkgit:git-diff-files[1] for more options.
-c::
This flag changes the way a merge commit is displayed. It shows
the differences from each of the parents to the merge result
simultaneously instead of showing pairwise diff between a parent
and the result one at a time. Furthermore, it lists only files
which were modified from all parents.
--cc::
This flag implies the '-c' options and further compresses the
patch output by omitting hunks that show differences from only
one parent, or show the same change from all but one parent for
an Octopus merge.
-r::
Show recursive diffs.
-t::
Show the tree objects in the diff output. This implies '-r'.
Commit Limiting
~~~~~~~~~~~~~~~
Besides specifying a range of commits that should be listed using the
special notations explained in the description, additional commit
limiting may be applied.
--
-n 'number', --max-count='number'::
Limit the number of commits output.
--skip='number'::
Skip 'number' commits before starting to show the commit output.
--since='date', --after='date'::
Show commits more recent than a specific date.
--until='date', --before='date'::
Show commits older than a specific date.
--max-age='timestamp', --min-age='timestamp'::
Limit the commits output to specified time range.
--author='pattern', --committer='pattern'::
Limit the commits output to ones with author/committer
header lines that match the specified pattern (regular expression).
--grep='pattern'::
Limit the commits output to ones with log message that
matches the specified pattern (regular expression).
-i, --regexp-ignore-case::
Match the regexp limiting patterns without regard to letters case.
-E, --extended-regexp::
Consider the limiting patterns to be extended regular expressions
instead of the default basic regular expressions.
--remove-empty::
Stop when a given path disappears from the tree.
--full-history::
Show also parts of history irrelevant to current state of a given
path. This turns off history simplification, which removed merges
which didn't change anything at all at some child. It will still actually
simplify away merges that didn't change anything at all into either
child.
--no-merges::
Do not print commits with more than one parent.
--first-parent::
Follow only the first parent commit upon seeing a merge
commit. This option can give a better overview when
viewing the evolution of a particular topic branch,
because merges into a topic branch tend to be only about
adjusting to updated upstream from time to time, and
this option allows you to ignore the individual commits
brought in to your history by such a merge.
--not::
Reverses the meaning of the '{caret}' prefix (or lack thereof)
for all following revision specifiers, up to the next '--not'.
--all::
Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the
command line as '<commit>'.
--stdin::
In addition to the '<commit>' listed on the command
line, read them from the standard input.
--quiet::
Don't print anything to standard output. This form
is primarily meant to allow the caller to
test the exit status to see if a range of objects is fully
connected (or not). It is faster than redirecting stdout
to /dev/null as the output does not have to be formatted.
--cherry-pick::
Omit any commit that introduces the same change as
another commit on the "other side" when the set of
commits are limited with symmetric difference.
+
For example, if you have two branches, `A` and `B`, a usual way
to list all commits on only one side of them is with
`--left-right`, like the example above in the description of
that option. It however shows the commits that were cherry-picked
from the other branch (for example, "3rd on b" may be cherry-picked
from branch A). With this option, such pairs of commits are
excluded from the output.
-g, --walk-reflogs::
Instead of walking the commit ancestry chain, walk
reflog entries from the most recent one to older ones.
When this option is used you cannot specify commits to
exclude (that is, '{caret}commit', 'commit1..commit2',
nor 'commit1...commit2' notations cannot be used).
+
With '\--pretty' format other than oneline (for obvious reasons),
this causes the output to have two extra lines of information
taken from the reflog. By default, 'commit@\{Nth}' notation is
used in the output. When the starting commit is specified as
'commit@{now}', output also uses 'commit@\{timestamp}' notation
instead. Under '\--pretty=oneline', the commit message is
prefixed with this information on the same line.
Cannot be combined with '\--reverse'.
See also linkgit:git-reflog[1].
--merge::
After a failed merge, show refs that touch files having a
conflict and don't exist on all heads to merge.
--boundary::
Output uninteresting commits at the boundary, which are usually
not shown.
--dense, --sparse::
When optional paths are given, the default behaviour ('--dense') is to
only output commits that changes at least one of them, and also ignore
merges that do not touch the given paths.
Use the '--sparse' flag to makes the command output all eligible commits
(still subject to count and age limitation), but apply merge
simplification nevertheless.
ifdef::git-rev-list[]
--bisect::
Limit output to the one commit object which is roughly halfway between
the included and excluded commits. Thus, if
-----------------------------------------------------------------------
$ git-rev-list --bisect foo ^bar ^baz
-----------------------------------------------------------------------
outputs 'midpoint', the output of the two commands
-----------------------------------------------------------------------
$ git-rev-list foo ^midpoint
$ git-rev-list midpoint ^bar ^baz
-----------------------------------------------------------------------
would be of roughly the same length. Finding the change which
introduces a regression is thus reduced to a binary search: repeatedly
generate and test new 'midpoint's until the commit chain is of length
one.
--bisect-vars::
This calculates the same as `--bisect`, but outputs text ready
to be eval'ed by the shell. These lines will assign the name of
the midpoint revision to the variable `bisect_rev`, and the
expected number of commits to be tested after `bisect_rev` is
tested to `bisect_nr`, the expected number of commits to be
tested if `bisect_rev` turns out to be good to `bisect_good`,
the expected number of commits to be tested if `bisect_rev`
turns out to be bad to `bisect_bad`, and the number of commits
we are bisecting right now to `bisect_all`.
--bisect-all::
This outputs all the commit objects between the included and excluded
commits, ordered by their distance to the included and excluded
commits. The farthest from them is displayed first. (This is the only
one displayed by `--bisect`.)
This is useful because it makes it easy to choose a good commit to
test when you want to avoid to test some of them for some reason (they
may not compile for example).
This option can be used along with `--bisect-vars`, in this case,
after all the sorted commit objects, there will be the same text as if
`--bisect-vars` had been used alone.
endif::git-rev-list[]
--
Commit Ordering
~~~~~~~~~~~~~~~
By default, the commits are shown in reverse chronological order.
--topo-order::
This option makes them appear in topological order (i.e.
descendant commits are shown before their parents).
--date-order::
This option is similar to '--topo-order' in the sense that no
parent comes before all of its children, but otherwise things
are still ordered in the commit timestamp order.
--reverse::
Output the commits in reverse order.
Cannot be combined with '\--walk-reflogs'.
Object Traversal
~~~~~~~~~~~~~~~~
These options are mostly targeted for packing of git repositories.
--objects::
Print the object IDs of any object referenced by the listed
commits. '--objects foo ^bar' thus means "send me
all object IDs which I need to download if I have the commit
object 'bar', but not 'foo'".
--objects-edge::
Similar to '--objects', but also print the IDs of excluded
commits prefixed with a "-" character. This is used by
linkgit:git-pack-objects[1] to build "thin" pack, which records
objects in deltified form based on objects contained in these
excluded commits to reduce network traffic.
--unpacked::
Only useful with '--objects'; print the object IDs that are not
in packs.
--no-walk::
Only show the given revs, but do not traverse their ancestors.
--do-walk::
Overrides a previous --no-walk.

View File

@@ -1,12 +1,74 @@
lockfile API
============
Talk about <lockfile.c>, things like:
The lockfile API serves two purposes:
* lockfile lifetime -- atexit(3) looks at them, do not put them on the
stack;
* hold_lock_file_for_update()
* commit_lock_file()
* rollback_rock_file()
* Mutual exclusion. When we write out a new index file, first
we create a new file `$GIT_DIR/index.lock`, write the new
contents into it, and rename it to the final destination
`$GIT_DIR/index`. We try to create the `$GIT_DIR/index.lock`
file with O_EXCL so that we can notice and fail when somebody
else is already trying to update the index file.
(JC, Dscho, Shawn)
* Automatic cruft removal. After we create the "lock" file, we
may decide to `die()`, and we would want to make sure that we
remove the file that has not been committed to its final
destination. This is done by remembering the lockfiles we
created in a linked list and cleaning them up from an
`atexit(3)` handler. Outstanding lockfiles are also removed
when the program dies on a signal.
The functions
-------------
hold_lock_file_for_update::
Take a pointer to `struct lock_file`, the filename of
the final destination (e.g. `$GIT_DIR/index`) and a flag
`die_on_error`. Attempt to create a lockfile for the
destination and return the file descriptor for writing
to the file. If `die_on_error` flag is true, it dies if
a lock is already taken for the file; otherwise it
returns a negative integer to the caller on failure.
commit_lock_file::
Take a pointer to the `struct lock_file` initialized
with an earlier call to `hold_lock_file_for_update()`,
close the file descriptor and rename the lockfile to its
final destination. Returns 0 upon success, a negative
value on failure to close(2) or rename(2).
rollback_lock_file::
Take a pointer to the `struct lock_file` initialized
with an earlier call to `hold_lock_file_for_update()`,
close the file descriptor and remove the lockfile.
close_lock_file::
Take a pointer to the `struct lock_file` initialized
with an earlier call to `hold_lock_file_for_update()`,
and close the file descriptor. Returns 0 upon success,
a negative value on failure to close(2).
Because the structure is used in an `atexit(3)` handler, its
storage has to stay throughout the life of the program. It
cannot be an auto variable allocated on the stack.
Call `commit_lock_file()` or `rollback_lock_file()` when you are
done writing to the file descriptor. If you do not call either
and simply `exit(3)` from the program, an `atexit(3)` handler
will close and remove the lockfile.
If you need to close the file descriptor you obtained from
`hold_lock_file_for_update` function yourself, do so by calling
`close_lock_file()`. You should never call `close(2)` yourself!
Otherwise the `struct
lock_file` structure still remembers that the file descriptor
needs to be closed, and a later call to `commit_lock_file()` or
`rollback_lock_file()` will result in duplicate calls to
`close(2)`. Worse yet, if you `close(2)`, open another file
descriptor for completely different purpose, and then call
`commit_lock_file()` or `rollback_lock_file()`, they may close
that unrelated file descriptor.

View File

@@ -38,6 +38,8 @@ all::
#
# Define NO_SETENV if you don't have setenv in the C library.
#
# Define NO_UNSETENV if you don't have unsetenv in the C library.
#
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
#
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
@@ -315,7 +317,7 @@ LIB_OBJS = \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
transport.o bundle.o walker.o parse-options.o ws.o
transport.o bundle.o walker.o parse-options.o ws.o archive.o
BUILTIN_OBJS = \
builtin-add.o \
@@ -1185,7 +1187,7 @@ check-docs::
case "$$v" in \
git-merge-octopus | git-merge-ours | git-merge-recursive | \
git-merge-resolve | git-merge-stupid | git-merge-subtree | \
git-fsck-objects | git-init-db | git-repo-config | \
git-fsck-objects | git-init-db | \
git-?*--?* ) continue ;; \
esac ; \
test -f "Documentation/$$v.txt" || \
@@ -1227,3 +1229,4 @@ check-docs::
#
check-builtins::
./check-builtins.sh

84
archive.c Normal file
View File

@@ -0,0 +1,84 @@
#include "cache.h"
#include "commit.h"
#include "attr.h"
static void format_subst(const struct commit *commit,
const char *src, size_t len,
struct strbuf *buf)
{
char *to_free = NULL;
struct strbuf fmt;
if (src == buf->buf)
to_free = strbuf_detach(buf, NULL);
strbuf_init(&fmt, 0);
for (;;) {
const char *b, *c;
b = memmem(src, len, "$Format:", 8);
if (!b || src + len < b + 9)
break;
c = memchr(b + 8, '$', len - 8);
if (!c)
break;
strbuf_reset(&fmt);
strbuf_add(&fmt, b + 8, c - b - 8);
strbuf_add(buf, src, b - src);
format_commit_message(commit, fmt.buf, buf);
len -= c + 1 - src;
src = c + 1;
}
strbuf_add(buf, src, len);
strbuf_release(&fmt);
free(to_free);
}
static int convert_to_archive(const char *path,
const void *src, size_t len,
struct strbuf *buf,
const struct commit *commit)
{
static struct git_attr *attr_export_subst;
struct git_attr_check check[1];
if (!commit)
return 0;
if (!attr_export_subst)
attr_export_subst = git_attr("export-subst", 12);
check[0].attr = attr_export_subst;
if (git_checkattr(path, ARRAY_SIZE(check), check))
return 0;
if (!ATTR_TRUE(check[0].value))
return 0;
format_subst(commit, src, len, buf);
return 1;
}
void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *sizep,
const struct commit *commit)
{
void *buffer;
buffer = read_sha1_file(sha1, type, sizep);
if (buffer && S_ISREG(mode)) {
struct strbuf buf;
size_t size = 0;
strbuf_init(&buf, 0);
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
convert_to_working_tree(path, buf.buf, buf.len, &buf);
convert_to_archive(path, buf.buf, buf.len, &buf, commit);
buffer = strbuf_detach(&buf, &size);
*sizep = size;
}
return buffer;
}

View File

@@ -259,7 +259,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
finish:
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(&lock_file))
commit_locked_index(&lock_file))
die("Unable to write new index file");
}

View File

@@ -2921,7 +2921,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
if (update_index) {
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(&lock_file))
commit_locked_index(&lock_file))
die("Unable to write new index file");
}

View File

@@ -79,86 +79,6 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}
static void format_subst(const struct commit *commit,
const char *src, size_t len,
struct strbuf *buf)
{
char *to_free = NULL;
struct strbuf fmt;
if (src == buf->buf)
to_free = strbuf_detach(buf, NULL);
strbuf_init(&fmt, 0);
for (;;) {
const char *b, *c;
b = memmem(src, len, "$Format:", 8);
if (!b || src + len < b + 9)
break;
c = memchr(b + 8, '$', len - 8);
if (!c)
break;
strbuf_reset(&fmt);
strbuf_add(&fmt, b + 8, c - b - 8);
strbuf_add(buf, src, b - src);
format_commit_message(commit, fmt.buf, buf);
len -= c + 1 - src;
src = c + 1;
}
strbuf_add(buf, src, len);
strbuf_release(&fmt);
free(to_free);
}
static int convert_to_archive(const char *path,
const void *src, size_t len,
struct strbuf *buf,
const struct commit *commit)
{
static struct git_attr *attr_export_subst;
struct git_attr_check check[1];
if (!commit)
return 0;
if (!attr_export_subst)
attr_export_subst = git_attr("export-subst", 12);
check[0].attr = attr_export_subst;
if (git_checkattr(path, ARRAY_SIZE(check), check))
return 0;
if (!ATTR_TRUE(check[0].value))
return 0;
format_subst(commit, src, len, buf);
return 1;
}
void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *sizep,
const struct commit *commit)
{
void *buffer;
buffer = read_sha1_file(sha1, type, sizep);
if (buffer && S_ISREG(mode)) {
struct strbuf buf;
size_t size = 0;
strbuf_init(&buf, 0);
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
convert_to_working_tree(path, buf.buf, buf.len, &buf);
convert_to_archive(path, buf.buf, buf.len, &buf, commit);
buffer = strbuf_detach(&buf, &size);
*sizep = size;
}
return buffer;
}
static int init_archiver(const char *name, struct archiver *ar)
{
int rv = -1, i;

View File

@@ -246,8 +246,8 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
* want to update cache.
*/
if (state.refresh_cache) {
close(newfd); newfd = -1;
rollback_lock_file(&lock_file);
newfd = -1;
}
state.refresh_cache = 0;
}
@@ -297,7 +297,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
if (0 <= newfd &&
(write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(&lock_file)))
commit_locked_index(&lock_file)))
die("Unable to write new index file");
return 0;
}

View File

@@ -90,7 +90,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
strbuf_init(&directory, 0);
if (pathspec)
seen = xmalloc(argc);
seen = xmalloc(argc > 0 ? argc : 1);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
@@ -125,7 +125,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
continue;
if (pathspec) {
memset(seen, 0, argc);
memset(seen, 0, argc > 0 ? argc : 1);
matches = match_pathspec(pathspec, ent->name, ent->len,
baselen, seen);
} else {

View File

@@ -21,6 +21,7 @@
#include "utf8.h"
#include "parse-options.h"
#include "path-list.h"
#include "unpack-trees.h"
static const char * const builtin_commit_usage[] = {
"git-commit [options] [--] <filepattern>...",
@@ -177,10 +178,34 @@ static void add_remove_files(struct path_list *list)
}
}
static void create_base_index(void)
{
struct tree *tree;
struct unpack_trees_options opts;
struct tree_desc t;
if (initial_commit) {
discard_cache();
return;
}
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
opts.index_only = 1;
opts.merge = 1;
opts.fn = oneway_merge;
tree = parse_tree_indirect(head_sha1);
if (!tree)
die("failed to unpack HEAD tree object");
parse_tree(tree);
init_tree_desc(&t, tree->buffer, tree->size);
unpack_trees(1, &t, &opts);
}
static char *prepare_index(int argc, const char **argv, const char *prefix)
{
int fd;
struct tree *tree;
struct path_list partial;
const char **pathspec = NULL;
@@ -212,7 +237,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
int fd = hold_locked_index(&index_lock, 1);
add_files_to_cache(0, also ? prefix : NULL, pathspec);
refresh_cache(REFRESH_QUIET);
if (write_cache(fd, active_cache, active_nr) || close(fd))
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die("unable to write new_index file");
commit_style = COMMIT_NORMAL;
return index_lock.filename;
@@ -231,7 +257,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
fd = hold_locked_index(&index_lock, 1);
refresh_cache(REFRESH_QUIET);
if (write_cache(fd, active_cache, active_nr) ||
close(fd) || commit_locked_index(&index_lock))
commit_locked_index(&index_lock))
die("unable to write new_index file");
commit_style = COMMIT_AS_IS;
return get_index_file();
@@ -273,23 +299,19 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
fd = hold_locked_index(&index_lock, 1);
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
if (write_cache(fd, active_cache, active_nr) || close(fd))
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die("unable to write new_index file");
fd = hold_lock_file_for_update(&false_lock,
git_path("next-index-%d", getpid()), 1);
discard_cache();
if (!initial_commit) {
tree = parse_tree_indirect(head_sha1);
if (!tree)
die("failed to unpack HEAD tree object");
if (read_tree(tree, 0, NULL))
die("failed to read HEAD tree object");
}
create_base_index();
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
if (write_cache(fd, active_cache, active_nr) || close(fd))
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&false_lock))
die("unable to write temporary index file");
return false_lock.filename;
}
@@ -737,6 +759,17 @@ static const char commit_utf8_warn[] =
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitencoding to the encoding your project uses.\n";
static void add_parent(struct strbuf *sb, const unsigned char *sha1)
{
struct object *obj = parse_object(sha1);
const char *parent = sha1_to_hex(sha1);
if (!obj)
die("Unable to find commit parent %s", parent);
if (obj->type != OBJ_COMMIT)
die("Parent %s isn't a proper commit", parent);
strbuf_addf(sb, "parent %s\n", parent);
}
int cmd_commit(int argc, const char **argv, const char *prefix)
{
int header_len;
@@ -799,21 +832,24 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
die("could not parse HEAD commit");
for (c = commit->parents; c; c = c->next)
strbuf_addf(&sb, "parent %s\n",
sha1_to_hex(c->item->object.sha1));
add_parent(&sb, c->item->object.sha1);
} else if (in_merge) {
struct strbuf m;
FILE *fp;
reflog_msg = "commit (merge)";
strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
add_parent(&sb, head_sha1);
strbuf_init(&m, 0);
fp = fopen(git_path("MERGE_HEAD"), "r");
if (fp == NULL)
die("could not open %s for reading: %s",
git_path("MERGE_HEAD"), strerror(errno));
while (strbuf_getline(&m, fp, '\n') != EOF)
strbuf_addf(&sb, "parent %s\n", m.buf);
while (strbuf_getline(&m, fp, '\n') != EOF) {
unsigned char sha1[20];
if (get_sha1_hex(m.buf, sha1) < 0)
die("Corrupt MERGE_HEAD file (%s)", m.buf);
add_parent(&sb, sha1);
}
fclose(fp);
strbuf_release(&m);
} else {

View File

@@ -190,7 +190,7 @@ static void refresh_index_quietly(void)
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
if (active_cache_changed &&
!write_cache(fd, active_cache, active_nr) && !close(fd))
!write_cache(fd, active_cache, active_nr))
commit_locked_index(lock_file);
rollback_lock_file(lock_file);

View File

@@ -783,7 +783,6 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
unlink(shallow);
rollback_lock_file(&lock);
} else {
close(fd);
commit_lock_file(&lock);
}
}

View File

@@ -555,20 +555,23 @@ static int fsck_handle_reflog(const char *logname, const unsigned char *sha1, in
return 0;
}
static int is_branch(const char *refname)
{
return !strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/");
}
static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
struct object *obj;
obj = lookup_object(sha1);
obj = parse_object(sha1);
if (!obj) {
if (has_sha1_file(sha1)) {
default_refs++;
return 0; /* it is in a pack */
}
error("%s: invalid sha1 pointer %s", refname, sha1_to_hex(sha1));
/* We'll continue with the rest despite the error.. */
return 0;
}
if (obj->type != OBJ_COMMIT && is_branch(refname))
error("%s: not a commit", refname);
default_refs++;
obj->used = 1;
mark_reachable(obj, REACHABLE);

View File

@@ -9,6 +9,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
const char **write_ref = NULL;
char **commit_id;
const char *url;
char *rewritten_url = NULL;
int arg = 1;
int rc = 0;
int get_tree = 0;
@@ -51,6 +52,12 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
commits = 1;
}
url = argv[arg];
if (url && url[strlen(url)-1] != '/') {
rewritten_url = malloc(strlen(url)+2);
strcpy(rewritten_url, url);
strcat(rewritten_url, "/");
url = rewritten_url;
}
walker = get_http_walker(url);
walker->get_tree = get_tree;
@@ -73,5 +80,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
walker_free(walker);
if (rewritten_url)
free(rewritten_url);
return rc;
}

View File

@@ -54,11 +54,11 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
uploadpack = arg + 7;
continue;
}
if (!strcmp("--tags", arg)) {
if (!strcmp("--tags", arg) || !strcmp("-t", arg)) {
flags |= REF_TAGS;
continue;
}
if (!strcmp("--heads", arg)) {
if (!strcmp("--heads", arg) || !strcmp("-h", arg)) {
flags |= REF_HEADS;
continue;
}

View File

@@ -264,7 +264,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) ||
commit_locked_index(&lock_file))
die("Unable to write new index file");
}

View File

@@ -108,6 +108,12 @@ static int pack_refs(unsigned int flags)
die("failed to write ref-pack file");
if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
die("failed to write ref-pack file (%s)", strerror(errno));
/*
* Since the lock file was fdopen()'ed and then fclose()'ed above,
* assign -1 to the lock file descriptor so that commit_lock_file()
* won't try to close() it.
*/
packed.fd = -1;
if (commit_lock_file(&packed) < 0)
die("unable to overwrite old ref-pack file (%s)", strerror(errno));
if (cbdata.flags & PACK_REFS_PRUNE)

View File

@@ -283,7 +283,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
}
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(&lock_file))
commit_locked_index(&lock_file))
die("unable to write new index file");
return 0;
}

View File

@@ -61,9 +61,9 @@ static int write_rr(struct path_list *rr, int out_fd)
write_in_full(out_fd, path, length) != length)
die("unable to write rerere record");
}
if (close(out_fd) != 0)
if (commit_lock_file(&write_lock) != 0)
die("unable to write rerere record");
return commit_lock_file(&write_lock);
return 0;
}
static int handle_file(const char *path,

View File

@@ -108,7 +108,6 @@ static int update_index_refresh(int fd, struct lock_file *index_lock)
return error("Could not read index");
result = refresh_cache(0) ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
close(fd) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");
return result;

View File

@@ -371,13 +371,13 @@ static int revert_or_cherry_pick(int argc, const char **argv)
i++;
}
}
if (close(msg_fd) || commit_lock_file(&msg_file) < 0)
if (commit_lock_file(&msg_file) < 0)
die ("Error wrapping up %s", defmsg);
fprintf(stderr, "Automatic %s failed.%s\n",
me, help_msg(commit->object.sha1));
exit(1);
}
if (close(msg_fd) || commit_lock_file(&msg_file) < 0)
if (commit_lock_file(&msg_file) < 0)
die ("Error wrapping up %s", defmsg);
fprintf(stderr, "Finished one %s.\n", me);

View File

@@ -250,7 +250,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(&lock_file))
commit_locked_index(&lock_file))
die("Unable to write new index file");
}

View File

@@ -738,7 +738,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
get_index_file(), strerror(lock_error));
}
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) || commit_locked_index(lock_file))
commit_locked_index(lock_file))
die("Unable to write new index file");
}

View File

@@ -35,11 +35,9 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
missing_ok, 0) < 0)
die("git-write-tree: error building trees");
if (0 <= newfd) {
if (!write_cache(newfd, active_cache, active_nr)
&& !close(newfd)) {
commit_lock_file(lock_file);
if (!write_cache(newfd, active_cache, active_nr) &&
!commit_lock_file(lock_file))
newfd = -1;
}
}
/* Not being able to write is fine -- we are only interested
* in updating the cache-tree part, and if the next caller
@@ -60,8 +58,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
hashcpy(sha1, active_cache_tree->sha1);
if (0 <= newfd)
close(newfd);
rollback_lock_file(lock_file);
rollback_lock_file(lock_file);
return 0;
}

View File

@@ -317,6 +317,14 @@ int create_bundle(struct bundle_header *header, const char *path,
rls.git_cmd = 1;
if (start_command(&rls))
return error("Could not spawn pack-objects");
/*
* start_command closed bundle_fd if it was > 1
* so set the lock fd to -1 so commit_lock_file()
* won't fail trying to close it.
*/
lock.fd = -1;
for (i = 0; i < revs.pending.nr; i++) {
struct object *object = revs.pending.objects[i].item;
if (object->flags & UNINTERESTING)
@@ -326,10 +334,8 @@ int create_bundle(struct bundle_header *header, const char *path,
}
if (finish_command(&rls))
return error ("pack-objects died");
close(bundle_fd);
if (!bundle_to_stdout)
commit_lock_file(&lock);
return 0;
return bundle_to_stdout ? close(bundle_fd) : commit_lock_file(&lock);
}
int unbundle(struct bundle_header *header, int bundle_fd)

View File

@@ -308,7 +308,7 @@ extern int commit_lock_file(struct lock_file *);
extern int hold_locked_index(struct lock_file *, int);
extern int commit_locked_index(struct lock_file *);
extern void set_alternate_index_output(const char *);
extern int close_lock_file(struct lock_file *);
extern void rollback_lock_file(struct lock_file *);
extern int delete_ref(const char *, const unsigned char *sha1);
@@ -565,6 +565,7 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
extern void pack_report(void);
extern int open_pack_index(struct packed_git *);
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
extern void close_pack_windows(struct packed_git *);
extern void unuse_pack(struct pack_window **);
extern struct packed_git *add_packed_git(const char *, int, int);
extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);

View File

@@ -91,6 +91,7 @@ git-reflog ancillarymanipulators
git-relink ancillarymanipulators
git-remote ancillarymanipulators
git-repack ancillarymanipulators
git-repo-config ancillarymanipulators deprecated
git-request-pull foreignscminterface
git-rerere ancillaryinterrogators
git-reset mainporcelain common

View File

@@ -48,19 +48,32 @@ struct commit *lookup_commit(const unsigned char *sha1)
return check_commit(obj, sha1, 0);
}
static unsigned long parse_commit_date(const char *buf)
static unsigned long parse_commit_date(const char *buf, const char *tail)
{
unsigned long date;
const char *dateptr;
if (buf + 6 >= tail)
return 0;
if (memcmp(buf, "author", 6))
return 0;
while (*buf++ != '\n')
while (buf < tail && *buf++ != '\n')
/* nada */;
if (buf + 9 >= tail)
return 0;
if (memcmp(buf, "committer", 9))
return 0;
while (*buf++ != '>')
while (buf < tail && *buf++ != '>')
/* nada */;
date = strtoul(buf, NULL, 10);
if (buf >= tail)
return 0;
dateptr = buf;
while (buf < tail && *buf++ != '\n')
/* nada */;
if (buf >= tail)
return 0;
/* dateptr < buf && buf[-1] == '\n', so strtoul will stop at buf-1 */
date = strtoul(dateptr, NULL, 10);
if (date == ULONG_MAX)
date = 0;
return date;
@@ -236,9 +249,9 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
return 0;
item->object.parsed = 1;
tail += size;
if (tail <= bufptr + 5 || memcmp(bufptr, "tree ", 5))
if (tail <= bufptr + 46 || memcmp(bufptr, "tree ", 5) || bufptr[45] != '\n')
return error("bogus commit object %s", sha1_to_hex(item->object.sha1));
if (tail <= bufptr + 45 || get_sha1_hex(bufptr + 5, parent) < 0)
if (get_sha1_hex(bufptr + 5, parent) < 0)
return error("bad tree pointer in commit %s",
sha1_to_hex(item->object.sha1));
item->tree = lookup_tree(parent);
@@ -275,7 +288,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
n_refs++;
}
}
item->date = parse_commit_date(bufptr);
item->date = parse_commit_date(bufptr, tail);
if (track_object_refs) {
unsigned i = 0;

View File

@@ -955,14 +955,12 @@ int git_config_set_multivar(const char* key, const char* value,
munmap(contents, contents_sz);
}
if (close(fd) || commit_lock_file(lock) < 0) {
if (commit_lock_file(lock) < 0) {
fprintf(stderr, "Cannot commit config file!\n");
ret = 4;
goto out_free;
}
/* fd is closed, so don't try to close it below. */
fd = -1;
/*
* lock is committed, so don't try to roll it back below.
* NOTE: Since lockfile.c keeps a linked list of all created
@@ -973,8 +971,6 @@ int git_config_set_multivar(const char* key, const char* value,
ret = 0;
out_free:
if (0 <= fd)
close(fd);
if (lock)
rollback_lock_file(lock);
free(config_filename);
@@ -1072,7 +1068,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
}
fclose(config_file);
unlock_and_out:
if (close(out_fd) || commit_lock_file(lock) < 0)
if (commit_lock_file(lock) < 0)
ret = error("Cannot commit config file!");
out:
free(config_filename);

View File

@@ -40,6 +40,7 @@ NO_MEMMEM=@NO_MEMMEM@
NO_STRLCPY=@NO_STRLCPY@
NO_STRTOUMAX=@NO_STRTOUMAX@
NO_SETENV=@NO_SETENV@
NO_UNSETENV=@NO_UNSETENV@
NO_MKDTEMP=@NO_MKDTEMP@
NO_ICONV=@NO_ICONV@
OLD_ICONV=@OLD_ICONV@

View File

@@ -356,6 +356,12 @@ AC_CHECK_FUNC(setenv,
[NO_SETENV=YesPlease])
AC_SUBST(NO_SETENV)
#
# Define NO_UNSETENV if you don't have unsetenv in the C library.
AC_CHECK_FUNC(unsetenv,
[NO_UNSETENV=],
[NO_UNSETENV=YesPlease])
AC_SUBST(NO_UNSETENV)
#
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
AC_CHECK_FUNC(mkdtemp,
[NO_MKDTEMP=],

View File

@@ -333,7 +333,7 @@ __git_commands ()
read-tree) : plumbing;;
receive-pack) : plumbing;;
reflog) : plumbing;;
repo-config) : plumbing;;
repo-config) : deprecated;;
rerere) : plumbing;;
rev-list) : plumbing;;
rev-parse) : plumbing;;
@@ -970,18 +970,18 @@ _git_remote ()
while [ $c -lt $COMP_CWORD ]; do
i="${COMP_WORDS[c]}"
case "$i" in
add|show|prune|update) command="$i"; break ;;
add|rm|show|prune|update) command="$i"; break ;;
esac
c=$((++c))
done
if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
__gitcomp "add show prune update"
__gitcomp "add rm show prune update"
return
fi
case "$command" in
show|prune)
rm|show|prune)
__gitcomp "$(__git_remotes)"
;;
update)

View File

@@ -167,7 +167,7 @@ type=$(git cat-file -t $object) || exit 1
tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1
test -n "$username" ||
username=$(git repo-config user.signingkey) ||
username=$(git config user.signingkey) ||
username=$(expr "z$tagger" : 'z\(.*>\)')
trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python
""" hg-to-svn.py - A Mercurial to GIT converter
""" hg-to-git.py - A Mercurial to GIT converter
Copyright (C)2007 Stelian Pop <stelian@popies.net>
@@ -27,6 +27,8 @@ import re
hgvers = {}
# List of children for each hg revision
hgchildren = {}
# List of parents for each hg revision
hgparents = {}
# Current branch for each hg revision
hgbranch = {}
# Number of new changesets converted from hg
@@ -99,17 +101,19 @@ if state:
else:
print 'State does not exist, first run'
tip = os.popen('hg tip | head -1 | cut -f 2 -d :').read().strip()
tip = os.popen('hg tip --template "{rev}"').read()
print 'tip is', tip
# Calculate the branches
print 'analysing the branches...'
hgchildren["0"] = ()
hgparents["0"] = (None, None)
hgbranch["0"] = "master"
for cset in range(1, int(tip) + 1):
hgchildren[str(cset)] = ()
prnts = os.popen('hg log -r %d | grep ^parent: | cut -f 2 -d :' % cset).readlines()
if len(prnts) > 0:
prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().split(' ')
prnts = map(lambda x: x[:x.find(':')], prnts)
if prnts[0] != '':
parent = prnts[0].strip()
else:
parent = str(cset - 1)
@@ -120,6 +124,8 @@ for cset in range(1, int(tip) + 1):
else:
mparent = None
hgparents[str(cset)] = (parent, mparent)
if mparent:
# For merge changesets, take either one, preferably the 'master' branch
if hgbranch[mparent] == 'master':
@@ -147,34 +153,27 @@ for cset in range(int(tip) + 1):
hgnewcsets += 1
# get info
prnts = os.popen('hg log -r %d | grep ^parent: | cut -f 2 -d :' % cset).readlines()
if len(prnts) > 0:
parent = prnts[0].strip()
else:
parent = str(cset - 1)
if len(prnts) > 1:
mparent = prnts[1].strip()
else:
mparent = None
log_data = os.popen('hg log -r %d --template "{tags}\n{date|date}\n{author}\n"' % cset).readlines()
tag = log_data[0].strip()
date = log_data[1].strip()
user = log_data[2].strip()
parent = hgparents[str(cset)][0]
mparent = hgparents[str(cset)][1]
#get comment
(fdcomment, filecomment) = tempfile.mkstemp()
csetcomment = os.popen('hg log -r %d -v | grep -v ^changeset: | grep -v ^parent: | grep -v ^user: | grep -v ^date | grep -v ^files: | grep -v ^description: | grep -v ^tag:' % cset).read().strip()
csetcomment = os.popen('hg log -r %d --template "{desc}"' % cset).read().strip()
os.write(fdcomment, csetcomment)
os.close(fdcomment)
date = os.popen('hg log -r %d | grep ^date: | cut -f 2- -d :' % cset).read().strip()
tag = os.popen('hg log -r %d | grep ^tag: | cut -f 2- -d :' % cset).read().strip()
user = os.popen('hg log -r %d | grep ^user: | cut -f 2- -d :' % cset).read().strip()
print '-----------------------------------------'
print 'cset:', cset
print 'branch:', hgbranch[str(cset)]
print 'user:', user
print 'date:', date
print 'comment:', csetcomment
print 'parent:', parent
if parent:
print 'parent:', parent
if mparent:
print 'mparent:', mparent
if tag:
@@ -224,8 +223,7 @@ for cset in range(int(tip) + 1):
os.system('git-branch -d %s' % otherbranch)
# retrieve and record the version
vvv = os.popen('git-show | head -1').read()
vvv = vvv[vvv.index(' ') + 1 : ].strip()
vvv = os.popen('git-show --quiet --pretty=format:%H').read()
print 'record', cset, '->', vvv
hgvers[str(cset)] = vvv

View File

@@ -248,24 +248,24 @@ generate_update_branch_email()
# In this case we want to issue an email containing only revisions
# 3, 4, and N. Given (almost) by
#
# git-rev-list N ^O --not --all
# git rev-list N ^O --not --all
#
# The reason for the "almost", is that the "--not --all" will take
# precedence over the "N", and effectively will translate to
#
# git-rev-list N ^O ^X ^N
# git rev-list N ^O ^X ^N
#
# So, we need to build up the list more carefully. git-rev-parse
# will generate a list of revs that may be fed into git-rev-list.
# So, we need to build up the list more carefully. git rev-parse
# will generate a list of revs that may be fed into git rev-list.
# We can get it to make the "--not --all" part and then filter out
# the "^N" with:
#
# git-rev-parse --not --all | grep -v N
# git rev-parse --not --all | grep -v N
#
# Then, using the --stdin switch to git-rev-list we have effectively
# Then, using the --stdin switch to git rev-list we have effectively
# manufactured
#
# git-rev-list N ^O ^X
# git rev-list N ^O ^X
#
# This leaves a problem when someone else updates the repository
# while this script is running. Their new value of the ref we're
@@ -274,10 +274,10 @@ generate_update_branch_email()
# all of our commits. What we really want is to exclude the current
# value of $refname from the --not list, rather than N itself. So:
#
# git-rev-parse --not --all | grep -v $(git-rev-parse $refname)
# git rev-parse --not --all | grep -v $(git rev-parse $refname)
#
# Get's us to something pretty safe (apart from the small time
# between refname being read, and git-rev-parse running - for that,
# between refname being read, and git rev-parse running - for that,
# I give up)
#
#
@@ -295,7 +295,7 @@ generate_update_branch_email()
# As above, we need to take into account the presence of X; if
# another branch is already in the repository and points at some of
# the revisions that we are about to output - we don't want them.
# The solution is as before: git-rev-parse output filtered.
# The solution is as before: git rev-parse output filtered.
#
# Finally, tags: 1 --- 2 --- O --- T --- 3 --- 4 --- N
#
@@ -305,7 +305,7 @@ generate_update_branch_email()
# for a branch update. Therefore we still want to output revisions
# that have been output on a tag email.
#
# Luckily, git-rev-parse includes just the tool. Instead of using
# Luckily, git rev-parse includes just the tool. Instead of using
# "--all" we use "--branches"; this has the added benefit that
# "remotes/" will be ignored as well.
@@ -454,7 +454,7 @@ generate_update_atag_email()
#
generate_atag_email()
{
# Use git-for-each-ref to pull out the individual fields from the
# Use git for-each-ref to pull out the individual fields from the
# tag
eval $(git for-each-ref --shell --format='
tagobject=%(*objectname)
@@ -572,7 +572,7 @@ generate_general_email()
else
# What can we do here? The tag marks an object that is not
# a commit, so there is no log for us to display. It's
# probably not wise to output git-cat-file as it could be a
# probably not wise to output git cat-file as it could be a
# binary blob. We'll just say how big it is
echo "$newrev is a $newrev_type, and is $(git cat-file -s $newrev) bytes long."
fi
@@ -622,10 +622,10 @@ then
projectdesc="UNNAMED PROJECT"
fi
recipients=$(git repo-config hooks.mailinglist)
announcerecipients=$(git repo-config hooks.announcelist)
envelopesender=$(git-repo-config hooks.envelopesender)
emailprefix=$(git-repo-config hooks.emailprefix || echo '[SCM] ')
recipients=$(git config hooks.mailinglist)
announcerecipients=$(git config hooks.announcelist)
envelopesender=$(git config hooks.envelopesender)
emailprefix=$(git config hooks.emailprefix || echo '[SCM] ')
# --- Main loop
# Allow dual mode: run from the command line just like the update hook, or

View File

@@ -17,8 +17,8 @@
#define CRLF_INPUT 2
struct text_stat {
/* CR, LF and CRLF counts */
unsigned cr, lf, crlf;
/* NUL, CR, LF and CRLF counts */
unsigned nul, cr, lf, crlf;
/* These are just approximations! */
unsigned printable, nonprintable;
@@ -51,6 +51,9 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat *
case '\b': case '\t': case '\033': case '\014':
stats->printable++;
break;
case 0:
stats->nul++;
/* fall through */
default:
stats->nonprintable++;
}
@@ -66,6 +69,8 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat *
static int is_binary(unsigned long size, struct text_stat *stats)
{
if (stats->nul)
return 1;
if ((stats->printable >> 7) < stats->nonprintable)
return 1;
/*

12
diff.c
View File

@@ -552,7 +552,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
int i;
int color;
struct emit_callback *ecbdata = priv;
const char *set = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
const char *meta = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
*(ecbdata->found_changesp) = 1;
@@ -564,9 +565,9 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
printf("%s--- %s%s%s\n",
set, ecbdata->label_path[0], reset, name_a_tab);
meta, ecbdata->label_path[0], reset, name_a_tab);
printf("%s+++ %s%s%s\n",
set, ecbdata->label_path[1], reset, name_b_tab);
meta, ecbdata->label_path[1], reset, name_b_tab);
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
}
@@ -586,7 +587,6 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
}
if (len < ecbdata->nparents) {
set = reset;
emit_line(reset, reset, line, len);
return;
}
@@ -610,7 +610,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
diff_words_show(ecbdata->diff_words);
line++;
len--;
emit_line(set, reset, line, len);
emit_line(plain, reset, line, len);
return;
}
for (i = 0; i < ecbdata->nparents && len; i++) {
@@ -1224,7 +1224,7 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)
/*
* And define built-in fallback patterns here. Note that
* these can be overriden by the user's config settings.
* these can be overridden by the user's config settings.
*/
for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++)
if (!strcmp(ident, builtin_funcname_pattern[i].name))

View File

@@ -917,6 +917,7 @@ static void end_packfile(void)
struct branch *b;
struct tag *t;
close_pack_windows(pack_data);
fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
pack_data->pack_name, object_count);
close(pack_data->pack_fd);
@@ -926,7 +927,6 @@ static void end_packfile(void)
new_p = add_packed_git(idx_name, strlen(idx_name), 1);
if (!new_p)
die("core git rejected index %s", idx_name);
new_p->windows = old_p->windows;
all_packs[pack_id] = new_p;
install_packed_git(new_p);
@@ -1129,8 +1129,10 @@ static void *gfi_unpack_entry(
{
enum object_type type;
struct packed_git *p = all_packs[oe->pack_id];
if (p == pack_data)
if (p == pack_data && p->pack_size < (pack_size + 20)) {
close_pack_windows(p);
p->pack_size = pack_size + 20;
}
return unpack_entry(p, oe->offset, &type, sizep);
}
@@ -1539,17 +1541,36 @@ static void dump_marks(void)
f = fdopen(mark_fd, "w");
if (!f) {
int saved_errno = errno;
rollback_lock_file(&mark_lock);
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
mark_file, strerror(saved_errno));
return;
}
/*
* Since the lock file was fdopen()'ed, it should not be close()'ed.
* Assign -1 to the lock file descriptor so that commit_lock_file()
* won't try to close() it.
*/
mark_lock.fd = -1;
dump_marks_helper(f, 0, marks);
fclose(f);
if (commit_lock_file(&mark_lock))
if (ferror(f) || fclose(f)) {
int saved_errno = errno;
rollback_lock_file(&mark_lock);
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
mark_file, strerror(saved_errno));
return;
}
if (commit_lock_file(&mark_lock)) {
int saved_errno = errno;
rollback_lock_file(&mark_lock);
failure |= error("Unable to commit marks file %s: %s",
mark_file, strerror(saved_errno));
return;
}
}
static int read_next_command(void)

View File

@@ -88,7 +88,7 @@ sub write_author_info($) {
close ($f);
}
# convert getopts specs for use by git-repo-config
# convert getopts specs for use by git config
sub read_repo_config {
# Split the string between characters, unless there is a ':'
# So "abc:de" becomes ["a", "b", "c:", "d", "e"]
@@ -96,7 +96,7 @@ sub read_repo_config {
foreach my $o (@opts) {
my $key = $o;
$key =~ s/://g;
my $arg = 'git-repo-config';
my $arg = 'git config';
$arg .= ' --bool' if ($o !~ /:$/);
chomp(my $tmp = `$arg --get cvsimport.$key`);
@@ -116,7 +116,7 @@ getopts($opts) or usage();
usage if $opt_h;
if (@ARGV == 0) {
chomp(my $module = `git-repo-config --get cvsimport.module`);
chomp(my $module = `git config --get cvsimport.module`);
push(@ARGV, $module) if $? == 0;
}
@ARGV <= 1 or usage("You can't specify more than one CVS module");

View File

@@ -110,7 +110,7 @@ TCLTK_PATH_SED = $(subst ','\'',$(subst \,\\,$(TCLTK_PATH)))
gg_libdir ?= $(sharedir)/git-gui/lib
libdir_SQ = $(subst ','\'',$(gg_libdir))
libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir)))
libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir_sed_in)))
exedir = $(dir $(gitexecdir))share/git-gui/lib
GITGUI_SCRIPT := $$0
@@ -119,11 +119,12 @@ GITGUI_MACOSXAPP :=
ifeq ($(uname_O),Cygwin)
GITGUI_SCRIPT := `cygpath --windows --absolute "$(GITGUI_SCRIPT)"`
gg_libdir := $(shell cygpath --windows --absolute "$(gg_libdir)")
gg_libdir_sed_in := $(shell cygpath --windows --absolute "$(gg_libdir)")
else
ifeq ($(exedir),$(gg_libdir))
GITGUI_RELATIVE := 1
endif
gg_libdir_sed_in := $(gg_libdir)
endif
ifeq ($(uname_S),Darwin)
ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y)

View File

@@ -290,11 +290,6 @@ method _write_local_path {args} {
}
method _git_init {} {
if {[file exists $local_path]} {
error_popup [mc "Location %s already exists." $local_path]
return 0
}
if {[catch {file mkdir $local_path} err]} {
error_popup [strcat \
[mc "Failed to create repository %s:" $local_path] \
@@ -417,41 +412,35 @@ method _new_local_path {} {
if {$p eq {}} return
set p [file normalize $p]
if {[file isdirectory $p]} {
foreach i [glob \
-directory $p \
-tails \
-nocomplain \
* .*] {
switch -- $i {
. continue
.. continue
default {
error_popup [mc "Directory %s already exists." $p]
return
}
}
}
if {[catch {file delete $p} err]} {
error_popup [strcat \
[mc "Directory %s already exists." $p] \
"\n\n$err"]
return
}
} elseif {[file exists $p]} {
error_popup [mc "File %s already exists." $p]
if {![_new_ok $p]} {
return
}
set local_path $p
}
method _do_new2 {} {
if {![_new_ok $local_path]} {
return
}
if {![_git_init $this]} {
return
}
set done 1
}
proc _new_ok {p} {
if {[file isdirectory $p]} {
if {[_is_git [file join $p .git]]} {
error_popup [mc "Directory %s already exists." $p]
return 0
}
} elseif {[file exists $p]} {
error_popup [mc "File %s already exists." $p]
return 0
}
return 1
}
######################################################################
##
## Clone Existing Repository
@@ -607,6 +596,11 @@ method _do_clone2 {} {
}
}
if {[file exists $local_path]} {
error_popup [mc "Location %s already exists." $local_path]
return
}
if {![_git_init $this]} return
set local_path [pwd]

View File

@@ -358,5 +358,7 @@ proc apply_hunk {x y} {
display_file $current_diff_path $mi
if {$o eq {_}} {
clear_diff
} else {
set current_diff_path $current_diff_path
}
}

View File

@@ -386,7 +386,9 @@ proc revert_helper {txt paths} {
set reply [tk_dialog \
.confirm_revert \
"[appname] ([reponame])" \
[mc "Any unstaged changes will be permanently lost by the revert."] \
"$query
[mc "Any unstaged changes will be permanently lost by the revert."]" \
question \
1 \
[mc "Do Nothing"] \

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-11-24 10:36+0100\n"
"PO-Revision-Date: 2007-11-24 10:55+0100\n"
"PO-Revision-Date: 2008-01-15 20:33+0100\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German\n"
"MIME-Version: 1.0\n"
@@ -272,7 +272,7 @@ msgstr "Neue Version"
#: git-gui.sh:1973 git-gui.sh:2357
msgid "Amend Last Commit"
msgstr "Letzte Version nachbessern"
msgstr "Letzte nachbessern"
#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99
msgid "Rescan"
@@ -284,7 +284,7 @@ msgstr "Zum Eintragen bereitstellen"
#: git-gui.sh:1994
msgid "Stage Changed Files To Commit"
msgstr "Geänderte Dateien zum Eintragen bereitstellen"
msgstr "Geänderte Dateien bereitstellen"
#: git-gui.sh:2000
msgid "Unstage From Commit"
@@ -292,7 +292,7 @@ msgstr "Aus der Bereitstellung herausnehmen"
#: git-gui.sh:2005 lib/index.tcl:393
msgid "Revert Changes"
msgstr "Änderungen revidieren"
msgstr "Änderungen verwerfen"
#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427
msgid "Sign Off"
@@ -351,7 +351,7 @@ msgstr "Aktueller Zweig:"
#: git-gui.sh:2255
msgid "Staged Changes (Will Commit)"
msgstr "Bereitgestellte Änderungen (zum Eintragen)"
msgstr "Bereitstellung (zum Eintragen)"
#: git-gui.sh:2274
msgid "Unstaged Changes"
@@ -403,7 +403,7 @@ msgstr "Aktualisieren"
#: git-gui.sh:2566
msgid "Apply/Reverse Hunk"
msgstr "Änderung anwenden/umkehren"
msgstr "Kontext anwenden/umkehren"
#: git-gui.sh:2572
msgid "Decrease Font Size"
@@ -415,19 +415,19 @@ msgstr "Schriftgröße vergrößern"
#: git-gui.sh:2581
msgid "Show Less Context"
msgstr "Weniger Kontext anzeigen"
msgstr "Weniger Zeilen anzeigen"
#: git-gui.sh:2588
msgid "Show More Context"
msgstr "Mehr Kontext anzeigen"
msgstr "Mehr Zeilen anzeigen"
#: git-gui.sh:2602
msgid "Unstage Hunk From Commit"
msgstr "Aus der Bereitstellung herausnehmen"
msgstr "Kontext aus Bereitstellung herausnehmen"
#: git-gui.sh:2604
msgid "Stage Hunk For Commit"
msgstr "In die Bereitstellung hinzufügen"
msgstr "Kontext zur Bereitstellung hinzufügen"
#: git-gui.sh:2623
msgid "Initializing..."
@@ -914,11 +914,11 @@ msgstr "Neu..."
#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468
msgid "Clone Existing Repository"
msgstr "Projektarchiv kopieren"
msgstr "Projektarchiv klonen"
#: lib/choose_repository.tcl:99
msgid "Clone..."
msgstr "Kopieren..."
msgstr "Klonen..."
#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978
msgid "Open Existing Repository"
@@ -968,7 +968,7 @@ msgstr "Datei »%s« existiert bereits."
#: lib/choose_repository.tcl:463
msgid "Clone"
msgstr "Kopieren"
msgstr "Klonen"
#: lib/choose_repository.tcl:476
msgid "URL:"
@@ -976,7 +976,7 @@ msgstr "URL:"
#: lib/choose_repository.tcl:496
msgid "Clone Type:"
msgstr "Art der Kopie:"
msgstr "Art des Klonens:"
#: lib/choose_repository.tcl:502
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
@@ -1025,7 +1025,7 @@ msgstr "Kopien von Objekten/Info/Alternates konnten nicht erstellt werden: %s"
#: lib/choose_repository.tcl:690
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "Von »%s« konnte nichts kopiert werden."
msgstr "Von »%s« konnte nichts geklont werden."
#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906
#: lib/choose_repository.tcl:918
@@ -1086,7 +1086,7 @@ msgstr "Verzeichnis »%s« kann nicht aufgeräumt werden."
#: lib/choose_repository.tcl:897
msgid "Clone failed."
msgstr "Kopieren fehlgeschlagen."
msgstr "Klonen fehlgeschlagen."
#: lib/choose_repository.tcl:904
msgid "No default branch obtained."
@@ -1440,11 +1440,11 @@ msgstr "Fehler beim Laden des Vergleichs:"
#: lib/diff.tcl:302
msgid "Failed to unstage selected hunk."
msgstr "Fehler beim Herausnehmen der gewählten Dateien aus der Bereitstellung."
msgstr "Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung."
#: lib/diff.tcl:309
msgid "Failed to stage selected hunk."
msgstr "Fehler beim Bereitstellen der gewählten Dateien."
msgstr "Fehler beim Bereitstellen des gewählten Kontexts."
#: lib/error.tcl:12 lib/error.tcl:102
msgid "error"
@@ -1494,17 +1494,16 @@ msgstr "»%s« hinzufügen..."
#: lib/index.tcl:381
#, tcl-format
msgid "Revert changes in file %s?"
msgstr "Änderungen in Datei »%s« revidieren?"
msgstr "Änderungen in Datei »%s« verwerfen?"
#: lib/index.tcl:383
#, tcl-format
msgid "Revert changes in these %i files?"
msgstr "Änderungen in den gewählten %i Dateien revidieren?"
msgstr "Änderungen in den gewählten %i Dateien verwerfen?"
#: lib/index.tcl:389
msgid "Any unstaged changes will be permanently lost by the revert."
msgstr ""
"Alle nicht bereitgestellten Änderungen werden beim Revidieren verloren gehen."
msgstr "Alle nicht bereitgestellten Änderungen werden beim Verwerfen verloren gehen."
#: lib/index.tcl:392
msgid "Do Nothing"
@@ -1730,7 +1729,7 @@ msgstr "Optionen konnten nicht gespeichert werden:"
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch"
msgstr "Zweig im anderen Projektarchiv löschen"
msgstr "Zweig aus anderem Projektarchiv löschen"
#: lib/remote_branch_delete.tcl:47
msgid "From Repository"
@@ -1852,7 +1851,7 @@ msgstr "Neue Änderungen von »%s« holen"
#: lib/transport.tcl:18
#, tcl-format
msgid "remote prune %s"
msgstr "Entfernen von »%s« im anderen Archiv"
msgstr "Entfernen von »%s« aus anderem Archiv"
#: lib/transport.tcl:19
#, tcl-format

1875
git-gui/po/fr.po Normal file

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-19 21:43+0200\n"
"PO-Revision-Date: 2007-10-20 15:24+0200\n"
"POT-Creation-Date: 2008-01-07 21:20+0100\n"
"PO-Revision-Date: 2008-01-15 20:32+0100\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German \n"
"MIME-Version: 1.0\n"
@@ -62,7 +62,7 @@ msgstr ""
#. ""
msgid "clone [verb]"
msgstr "kopieren"
msgstr "klonen"
#. "A single point in the git history."
msgid "commit [noun]"
@@ -92,6 +92,10 @@ msgstr "Schnellzusammenführung"
msgid "fetch"
msgstr "anfordern (holen?)"
#. "One context of consecutive lines in a whole patch, which consists of many such hunks"
msgid "hunk"
msgstr "Kontext"
#. "A collection of files. The index is a stored version of your working tree."
msgid "index (in git-gui: staging area)"
msgstr "Bereitstellung"
@@ -138,7 +142,7 @@ msgstr "zurücksetzen (zurückkehren?)"
#. ""
msgid "revert"
msgstr "revidieren"
msgstr "verwerfen (bei git-reset), revidieren (bei git-revert, also mit neuem commit)"
#. "A particular state of files and directories which was stored in the object database."
msgid "revision"

166
git-gui/po/glossary/fr.po Normal file
View File

@@ -0,0 +1,166 @@
# translation of fr.po to French
# Translation of git-gui glossary to French
# Copyright (C) 2008 Shawn Pearce, et al.
#
# Christian Couder <chriscool@tuxfamily.org>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: fr\n"
"POT-Creation-Date: 2008-01-15 21:04+0100\n"
"PO-Revision-Date: 2008-01-15 21:17+0100\n"
"Last-Translator: Christian Couder <chriscool@tuxfamily.org>\n"
"Language-Team: French\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
msgid "English Term (Dear translator: This file will never be visible to the user!)"
msgstr ""
#. ""
msgid "amend"
msgstr "corriger"
#. ""
msgid "annotate"
msgstr "annoter"
#. "A 'branch' is an active line of development."
msgid "branch [noun]"
msgstr "branche"
#. ""
msgid "branch [verb]"
msgstr "cr<63>er une branche"
#. ""
msgid "checkout [noun]"
msgstr "emprunt"
#. "The action of updating the working tree to a revision which was stored in the object database."
msgid "checkout [verb]"
msgstr "emprunter"
#. ""
msgid "clone [verb]"
msgstr "cloner"
#. "A single point in the git history."
msgid "commit [noun]"
msgstr "commit"
#. "The action of storing a new snapshot of the project's state in the git history."
msgid "commit [verb]"
msgstr "commiter"
#. ""
msgid "diff [noun]"
msgstr "diff<66>rence"
#. ""
msgid "diff [verb]"
msgstr "comparer"
#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
msgid "fast forward merge"
msgstr "fusion par avance rapide"
#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
msgid "fetch"
msgstr "r<>cup<75>rer"
#. "A collection of files. The index is a stored version of your working tree."
msgid "index (in git-gui: staging area)"
msgstr "pr<70>-commit"
#. "A successful merge results in the creation of a new commit representing the result of the merge."
msgid "merge [noun]"
msgstr "fusion"
#. "To bring the contents of another branch into the current branch."
msgid "merge [verb]"
msgstr "fusionner"
#. ""
msgid "message"
msgstr "message"
#. "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 "nettoyer"
#. "Pulling a branch means to fetch it and merge it."
msgid "pull"
msgstr "tirer"
#. "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 "pousser"
#. ""
msgid "redo"
msgstr "refaire"
#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
msgid "remote"
msgstr "r<>f<EFBFBD>rentiel distant"
#. "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 "r<>f<EFBFBD>rentiel"
#. ""
msgid "reset"
msgstr "r<>initialiser"
#. ""
msgid "revert"
msgstr "inverser"
#. "A particular state of files and directories which was stored in the object database."
msgid "revision"
msgstr "r<>vision"
#. ""
msgid "sign off"
msgstr "signer"
#. ""
msgid "staging area"
msgstr "pr<70>-commit"
#. ""
msgid "status"
msgstr "<22>tat"
#. "A ref pointing to a tag or commit object"
msgid "tag [noun]"
msgstr "marque"
#. ""
msgid "tag [verb]"
msgstr "marquer"
#. "A regular git branch that is used to follow changes from another repository."
msgid "tracking branch"
msgstr "branche de suivi"
#. ""
msgid "undo"
msgstr "d<>faire"
#. ""
msgid "update"
msgstr "mise <20> jour"
#. ""
msgid "verify"
msgstr "v<>rifier"
#. "The tree of actual checked out files."
msgid "working copy, working tree"
msgstr "copie de travail, arborescence de travail"

View File

@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2007-10-19 21:43+0200\n"
"POT-Creation-Date: 2008-01-07 21:20+0100\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"
@@ -70,6 +70,10 @@ msgstr ""
msgid "fetch"
msgstr ""
#. "One context of consecutive lines in a whole patch, which consists of many such hunks"
msgid "hunk"
msgstr ""
#. "A collection of files. The index is a stored version of your working tree."
msgid "index (in git-gui: staging area)"
msgstr ""

View File

@@ -12,6 +12,7 @@
"diff [verb]" ""
"fast forward merge" "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
"fetch" "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
"hunk" "One context of consecutive lines in a whole patch, which consists of many such hunks"
"index (in git-gui: staging area)" "A collection of files. The index is a stored version of your working tree."
"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."

View File

@@ -2,13 +2,13 @@
# Copyright (C) 2007 Shawn Pearce, et al.
# This file is distributed under the same license as the git-gui package.
#
# Peter Karlsson <peter@softwolves.pp.se>, 2007.
# Peter Karlsson <peter@softwolves.pp.se>, 2007-2008.
msgid ""
msgstr ""
"Project-Id-Version: sv\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-11-24 10:36+0100\n"
"PO-Revision-Date: 2007-12-27 13:31CET-1\n"
"PO-Revision-Date: 2008-01-12 09:27+0100\n"
"Last-Translator: Peter Karlsson <peter@softwolves.pp.se>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
@@ -67,11 +67,11 @@ msgstr "Git-katalogen hittades inte:"
#: git-gui.sh:895
msgid "Cannot move to top of working directory:"
msgstr "Kunde inte gå till början på arbetskatalogen:"
msgstr "Kan inte gå till början på arbetskatalogen:"
#: git-gui.sh:902
msgid "Cannot use funny .git directory:"
msgstr "Kunde inte använda underlig .git-katalog:"
msgstr "Kan inte använda underlig .git-katalog:"
#: git-gui.sh:907
msgid "No working directory"
@@ -87,7 +87,7 @@ msgstr "Söker efter ändrade filer..."
#: git-gui.sh:1294 lib/browser.tcl:245
msgid "Ready."
msgstr "Redo."
msgstr "Klar."
#: git-gui.sh:1560
msgid "Unmodified"
@@ -127,7 +127,7 @@ msgstr "Köade för borttagning, fortfarande närvarande"
#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579
msgid "Requires merge resolution"
msgstr "Kräver avgörande efter sammanslagning"
msgstr "Kräver konflikthantering efter sammanslagning"
#: git-gui.sh:1614
msgid "Starting gitk... please wait..."
@@ -499,23 +499,23 @@ msgstr "Läser %s..."
#: lib/blame.tcl:473
msgid "Loading copy/move tracking annotations..."
msgstr "Läser spårningsanteckningar för kopiering/flyttning..."
msgstr "Läser annoteringar för kopiering/flyttning..."
#: lib/blame.tcl:493
msgid "lines annotated"
msgstr "rader spårade"
msgstr "rader annoterade"
#: lib/blame.tcl:674
msgid "Loading original location annotations..."
msgstr "Läser in spårning av originalplacering..."
msgstr "Läser in annotering av originalplacering..."
#: lib/blame.tcl:677
msgid "Annotation complete."
msgstr "Spårning fullbordad."
msgstr "Annotering fullbordad."
#: lib/blame.tcl:731
msgid "Loading annotation..."
msgstr "Läser in spårning..."
msgstr "Läser in annotering..."
#: lib/blame.tcl:787
msgid "Author:"

View File

@@ -73,14 +73,19 @@ comment_for_reflog () {
esac
}
last_count=
mark_action_done () {
sed -e 1q < "$TODO" >> "$DONE"
sed -e 1d < "$TODO" >> "$TODO".new
mv -f "$TODO".new "$TODO"
count=$(($(grep -ve '^$' -e '^#' < "$DONE" | wc -l)))
total=$(($count+$(grep -ve '^$' -e '^#' < "$TODO" | wc -l)))
printf "Rebasing (%d/%d)\r" $count $total
test -z "$VERBOSE" || echo
if test "$last_count" != "$count"
then
last_count=$count
printf "Rebasing (%d/%d)\r" $count $total
test -z "$VERBOSE" || echo
fi
}
make_patch () {

View File

@@ -100,6 +100,8 @@ Options:
--envelope-sender Specify the envelope sender used to send the emails.
--no-validate Don't perform any sanity checks on patches.
EOT
exit(1);
}
@@ -177,6 +179,7 @@ my ($quiet, $dry_run) = (0, 0);
my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);
my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);
my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);
my ($no_validate);
my %config_bool_settings = (
"thread" => [\$thread, 1],
@@ -222,6 +225,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
"dry-run" => \$dry_run,
"envelope-sender=s" => \$envelope_sender,
"thread!" => \$thread,
"no-validate" => \$no_validate,
);
unless ($rc) {
@@ -314,6 +318,40 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
($sender) = expand_aliases($sender) if defined $sender;
# Now that all the defaults are set, process the rest of the command line
# arguments and collect up the files that need to be processed.
for my $f (@ARGV) {
if (-d $f) {
opendir(DH,$f)
or die "Failed to opendir $f: $!";
push @files, grep { -f $_ } map { +$f . "/" . $_ }
sort readdir(DH);
} elsif (-f $f) {
push @files, $f;
} else {
print STDERR "Skipping $f - not found.\n";
}
}
if (!$no_validate) {
foreach my $f (@files) {
my $error = validate_patch($f);
$error and die "fatal: $f: $error\nwarning: no patches were sent\n";
}
}
if (@files) {
unless ($quiet) {
print $_,"\n" for (@files);
}
} else {
print STDERR "\nNo patch files specified!\n\n";
usage();
}
my $prompting = 0;
if (!defined $sender) {
$sender = $repoauthor || $repocommitter;
@@ -427,34 +465,6 @@ EOT
@files = ($compose_filename . ".final");
}
# Now that all the defaults are set, process the rest of the command line
# arguments and collect up the files that need to be processed.
for my $f (@ARGV) {
if (-d $f) {
opendir(DH,$f)
or die "Failed to opendir $f: $!";
push @files, grep { -f $_ } map { +$f . "/" . $_ }
sort readdir(DH);
} elsif (-f $f) {
push @files, $f;
} else {
print STDERR "Skipping $f - not found.\n";
}
}
if (@files) {
unless ($quiet) {
print $_,"\n" for (@files);
}
} else {
print STDERR "\nNo patch files specified!\n\n";
usage();
}
# Variables we set as part of the loop over files
our ($message_id, %mail, $subject, $reply_to, $references, $message);
@@ -838,3 +848,15 @@ sub unique_email_list(@) {
}
return @emails;
}
sub validate_patch {
my $fn = shift;
open(my $fh, '<', $fn)
or die "unable to open $fn: $!\n";
while (my $line = <$fh>) {
if (length($line) > 998) {
return "$.: patch contains a line longer than 998 characters";
}
}
return undef;
}

View File

@@ -1758,10 +1758,16 @@ sub svnsync {
# see if we have it in our config, first:
eval {
my $section = "svn-remote.$self->{repo_id}";
$svnsync = {
url => tmp_config('--get', "$section.svnsync-url"),
uuid => tmp_config('--get', "$section.svnsync-uuid"),
}
my $url = tmp_config('--get', "$section.svnsync-url");
($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
die "doesn't look right - svn:sync-from-url is '$url'\n";
my $uuid = tmp_config('--get', "$section.svnsync-uuid");
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
$svnsync = { url => $url, uuid => $uuid }
};
if ($svnsync && $svnsync->{url} && $svnsync->{uuid}) {
return $self->{svnsync} = $svnsync;
@@ -1772,11 +1778,11 @@ sub svnsync {
my $rp = $self->ra->rev_proplist(0);
my $url = $rp->{'svn:sync-from-url'} or die $err . "url\n";
$url =~ m{^[a-z\+]+://} or
($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
die "doesn't look right - svn:sync-from-url is '$url'\n";
my $uuid = $rp->{'svn:sync-from-uuid'} or die $err . "uuid\n";
$uuid =~ m{^[0-9a-f\-]{30,}$} or
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
my $section = "svn-remote.$self->{repo_id}";

View File

@@ -996,6 +996,7 @@ proc makewindow {} {
bind . <$M1B-r> dosearchback
bind . <$M1B-s> dosearch
bind . <$M1B-equal> {incrfont 1}
bind . <$M1B-plus> {incrfont 1}
bind . <$M1B-KP_Add> {incrfont 1}
bind . <$M1B-minus> {incrfont -1}
bind . <$M1B-KP_Subtract> {incrfont -1}

View File

@@ -1563,9 +1563,17 @@ static int locking_available(void)
lock_flags = 0;
}
XML_ParserFree(parser);
if (!lock_flags)
error("Error: no DAV locking support on %s",
remote->url);
} else {
error("Cannot access URL %s, return code %d",
remote->url, results.curl_result);
lock_flags = 0;
}
} else {
fprintf(stderr, "Unable to start PROPFIND request\n");
error("Unable to start PROPFIND request on %s", remote->url);
}
strbuf_release(&out_buffer.buf);
@@ -2161,6 +2169,7 @@ int main(int argc, char **argv)
int i;
int new_refs;
struct ref *ref;
char *rewritten_url = NULL;
setup_git_directory();
@@ -2212,6 +2221,10 @@ int main(int argc, char **argv)
break;
}
#ifndef USE_CURL_MULTI
die("git-push is not available for http/https repository when not compiled with USE_CURL_MULTI");
#endif
if (!remote->url)
usage(http_push_usage);
@@ -2224,9 +2237,16 @@ int main(int argc, char **argv)
no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
if (remote->url && remote->url[strlen(remote->url)-1] != '/') {
rewritten_url = malloc(strlen(remote->url)+2);
strcpy(rewritten_url, remote->url);
strcat(rewritten_url, "/");
remote->url = rewritten_url;
++remote->path_len;
}
/* Verify DAV compliance/lock support */
if (!locking_available()) {
fprintf(stderr, "Error: no DAV locking support on remote repo %s\n", remote->url);
rc = 1;
goto cleanup;
}
@@ -2239,6 +2259,11 @@ int main(int argc, char **argv)
info_ref_lock = lock_remote("info/refs", LOCK_TIME);
if (info_ref_lock)
remote->can_update_info_refs = 1;
else {
fprintf(stderr, "Error: cannot lock existing info/refs\n");
rc = 1;
goto cleanup;
}
}
if (remote->has_info_packs)
fetch_indices();
@@ -2260,11 +2285,14 @@ int main(int argc, char **argv)
if (!remote_tail)
remote_tail = &remote_refs;
if (match_refs(local_refs, remote_refs, &remote_tail,
nr_refspec, (const char **) refspec, push_all))
return -1;
nr_refspec, (const char **) refspec, push_all)) {
rc = -1;
goto cleanup;
}
if (!remote_refs) {
fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
return 0;
rc = 0;
goto cleanup;
}
new_refs = 0;
@@ -2395,10 +2423,12 @@ int main(int argc, char **argv)
fprintf(stderr, "Unable to update server info\n");
}
}
if (info_ref_lock)
unlock_remote(info_ref_lock);
cleanup:
if (rewritten_url)
free(rewritten_url);
if (info_ref_lock)
unlock_remote(info_ref_lock);
free(remote);
curl_slist_free_all(no_pragma_header);

View File

@@ -13,7 +13,8 @@ static void remove_lock_file(void)
while (lock_file_list) {
if (lock_file_list->owner == me &&
lock_file_list->filename[0]) {
close(lock_file_list->fd);
if (lock_file_list->fd >= 0)
close(lock_file_list->fd);
unlink(lock_file_list->filename);
}
lock_file_list = lock_file_list->next;
@@ -159,17 +160,26 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on
return fd;
}
int close_lock_file(struct lock_file *lk)
{
int fd = lk->fd;
lk->fd = -1;
return close(fd);
}
int commit_lock_file(struct lock_file *lk)
{
char result_file[PATH_MAX];
int i;
close(lk->fd);
size_t i;
if (lk->fd >= 0 && close_lock_file(lk))
return -1;
strcpy(result_file, lk->filename);
i = strlen(result_file) - 5; /* .lock */
result_file[i] = 0;
i = rename(lk->filename, result_file);
if (rename(lk->filename, result_file))
return -1;
lk->filename[0] = 0;
return i;
return 0;
}
int hold_locked_index(struct lock_file *lk, int die_on_error)
@@ -185,9 +195,12 @@ void set_alternate_index_output(const char *name)
int commit_locked_index(struct lock_file *lk)
{
if (alternate_index_output) {
int result = rename(lk->filename, alternate_index_output);
if (lk->fd >= 0 && close_lock_file(lk))
return -1;
if (rename(lk->filename, alternate_index_output))
return -1;
lk->filename[0] = 0;
return result;
return 0;
}
else
return commit_lock_file(lk);
@@ -196,7 +209,8 @@ int commit_locked_index(struct lock_file *lk)
void rollback_lock_file(struct lock_file *lk)
{
if (lk->filename[0]) {
close(lk->fd);
if (lk->fd >= 0)
close(lk->fd);
unlink(lk->filename);
}
lk->filename[0] = 0;

View File

@@ -1753,7 +1753,7 @@ int main(int argc, char *argv[])
if (active_cache_changed &&
(write_cache(index_fd, active_cache, active_nr) ||
close(index_fd) || commit_locked_index(lock)))
commit_locked_index(lock)))
die ("unable to write %s", get_index_file());
return clean ? 0: 1;

50
refs.c
View File

@@ -864,7 +864,6 @@ static int repack_without_ref(const char *refname)
die("too long a refname '%s'", list->name);
write_or_die(fd, line, len);
}
close(fd);
return commit_lock_file(&packlock);
}
@@ -1019,14 +1018,27 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
return 1;
}
static int close_ref(struct ref_lock *lock)
{
if (close_lock_file(lock->lk))
return -1;
lock->lock_fd = -1;
return 0;
}
static int commit_ref(struct ref_lock *lock)
{
if (commit_lock_file(lock->lk))
return -1;
lock->lock_fd = -1;
return 0;
}
void unlock_ref(struct ref_lock *lock)
{
if (lock->lock_fd >= 0) {
close(lock->lock_fd);
/* Do not free lock->lk -- atexit() still looks at them */
if (lock->lk)
rollback_lock_file(lock->lk);
}
/* Do not free lock->lk -- atexit() still looks at them */
if (lock->lk)
rollback_lock_file(lock->lk);
free(lock->ref_name);
free(lock->orig_ref_name);
free(lock);
@@ -1119,10 +1131,16 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
return 0;
}
static int is_branch(const char *refname)
{
return !strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/");
}
int write_ref_sha1(struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg)
{
static char term = '\n';
struct object *o;
if (!lock)
return -1;
@@ -1130,9 +1148,22 @@ int write_ref_sha1(struct ref_lock *lock,
unlock_ref(lock);
return 0;
}
o = parse_object(sha1);
if (!o) {
error("Trying to write ref %s with nonexistant object %s",
lock->ref_name, sha1_to_hex(sha1));
unlock_ref(lock);
return -1;
}
if (o->type != OBJ_COMMIT && is_branch(lock->ref_name)) {
error("Trying to write non-commit object %s to branch %s",
sha1_to_hex(sha1), lock->ref_name);
unlock_ref(lock);
return -1;
}
if (write_in_full(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
write_in_full(lock->lock_fd, &term, 1) != 1
|| close(lock->lock_fd) < 0) {
|| close_ref(lock) < 0) {
error("Couldn't write %s", lock->lk->filename);
unlock_ref(lock);
return -1;
@@ -1165,12 +1196,11 @@ int write_ref_sha1(struct ref_lock *lock,
!strcmp(head_ref, lock->ref_name))
log_ref_write("HEAD", lock->old_sha1, sha1, logmsg);
}
if (commit_lock_file(lock->lk)) {
if (commit_ref(lock)) {
error("Couldn't set %s", lock->ref_name);
unlock_ref(lock);
return -1;
}
lock->lock_fd = -1;
unlock_ref(lock);
return 0;
}

View File

@@ -621,6 +621,22 @@ void release_pack_memory(size_t need, int fd)
; /* nothing */
}
void close_pack_windows(struct packed_git *p)
{
while (p->windows) {
struct pack_window *w = p->windows;
if (w->inuse_cnt)
die("pack '%s' still has open windows to it",
p->pack_name);
munmap(w->base, w->len);
pack_mapped -= w->len;
pack_open_windows--;
p->windows = w->next;
free(w);
}
}
void unuse_pack(struct pack_window **w_cursor)
{
struct pack_window *w = *w_cursor;

View File

@@ -19,7 +19,7 @@ remove_cr () {
test_expect_success setup '
git repo-config core.autocrlf false &&
git config core.autocrlf false &&
for w in Hello world how are you; do echo $w; done >one &&
mkdir dir &&
@@ -46,7 +46,7 @@ test_expect_success 'update with autocrlf=input' '
rm -f tmp one dir/two three &&
git read-tree --reset -u HEAD &&
git repo-config core.autocrlf input &&
git config core.autocrlf input &&
for f in one dir/two
do
@@ -70,7 +70,7 @@ test_expect_success 'update with autocrlf=true' '
rm -f tmp one dir/two three &&
git read-tree --reset -u HEAD &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
for f in one dir/two
do
@@ -93,7 +93,7 @@ test_expect_success 'update with autocrlf=true' '
test_expect_success 'checkout with autocrlf=true' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
for f in one dir/two
@@ -117,7 +117,7 @@ test_expect_success 'checkout with autocrlf=true' '
test_expect_success 'checkout with autocrlf=input' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf input &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
for f in one dir/two
@@ -143,7 +143,7 @@ test_expect_success 'checkout with autocrlf=input' '
test_expect_success 'apply patch (autocrlf=input)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf input &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
git apply patch.file &&
@@ -156,7 +156,7 @@ test_expect_success 'apply patch (autocrlf=input)' '
test_expect_success 'apply patch --cached (autocrlf=input)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf input &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
git apply --cached patch.file &&
@@ -169,7 +169,7 @@ test_expect_success 'apply patch --cached (autocrlf=input)' '
test_expect_success 'apply patch --index (autocrlf=input)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf input &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
git apply --index patch.file &&
@@ -183,7 +183,7 @@ test_expect_success 'apply patch --index (autocrlf=input)' '
test_expect_success 'apply patch (autocrlf=true)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
git apply patch.file &&
@@ -196,7 +196,7 @@ test_expect_success 'apply patch (autocrlf=true)' '
test_expect_success 'apply patch --cached (autocrlf=true)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
git apply --cached patch.file &&
@@ -209,7 +209,7 @@ test_expect_success 'apply patch --cached (autocrlf=true)' '
test_expect_success 'apply patch --index (autocrlf=true)' '
rm -f tmp one dir/two three &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
git apply --index patch.file &&
@@ -224,7 +224,7 @@ test_expect_success '.gitattributes says two is binary' '
rm -f tmp one dir/two three &&
echo "two -crlf" >.gitattributes &&
git repo-config core.autocrlf true &&
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
if remove_cr dir/two >/dev/null

View File

@@ -7,12 +7,19 @@ test_description='Test git update-ref and basic ref logging'
. ./test-lib.sh
Z=0000000000000000000000000000000000000000
A=1111111111111111111111111111111111111111
B=2222222222222222222222222222222222222222
C=3333333333333333333333333333333333333333
D=4444444444444444444444444444444444444444
E=5555555555555555555555555555555555555555
F=6666666666666666666666666666666666666666
test_expect_success setup '
for name in A B C D E F
do
test_tick &&
T=$(git write-tree) &&
sha1=$(echo $name | git commit-tree $T) &&
eval $name=$sha1
done
'
m=refs/heads/master
n_dir=refs/heads/gu
n=$n_dir/fixes

View File

@@ -22,7 +22,7 @@ echo 3 > a1
git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1
# now fsck up the utf8
git repo-config i18n.commitencoding non-utf-8
git config i18n.commitencoding non-utf-8
echo 4 > a1
git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1

View File

@@ -78,4 +78,34 @@ test_expect_success 'Show all headers' '
diff -u expected-show-all-headers actual-show-all-headers
'
z8=zzzzzzzz
z64=$z8$z8$z8$z8$z8$z8$z8$z8
z512=$z64$z64$z64$z64$z64$z64$z64$z64
test_expect_success 'reject long lines' '
rm -f commandline &&
cp $patches longline.patch &&
echo $z512$z512 >>longline.patch &&
! git send-email \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
$patches longline.patch \
2>errors &&
grep longline.patch errors
'
test_expect_success 'no patch was sent' '
! test -e commandline
'
test_expect_success 'allow long lines with --no-validate' '
git send-email \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
--no-validate \
$patches longline.patch \
2>errors
'
test_done

View File

@@ -225,7 +225,7 @@ test_expect_success \
! git-cvsexportcommit -c $id
)'
case "$(git repo-config --bool core.filemode)" in
case "$(git config --bool core.filemode)" in
false)
;;
*)

View File

@@ -61,7 +61,7 @@ perl -e '
if (/^\s* \t/) {
bad_line("indent SP followed by a TAB", $_);
}
if (/^(?:[<>=]){7}/) {
if (/^([<>])\1{6} |^={7}$/) {
bad_line("unresolved merge conflict", $_);
}
}

View File

@@ -37,9 +37,9 @@ if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
fi
# --- Config
allowunannotated=$(git-repo-config --bool hooks.allowunannotated)
allowdeletebranch=$(git-repo-config --bool hooks.allowdeletebranch)
allowdeletetag=$(git-repo-config --bool hooks.allowdeletetag)
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")