mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
@@ -5,7 +5,7 @@ User visible changes
|
||||
--------------------
|
||||
|
||||
With the default Makefile settings, most of the programs are now
|
||||
installed outside your $PATH, except for "git", "gitk", "git-gui" and
|
||||
installed outside your $PATH, except for "git", "gitk" and
|
||||
some server side programs that need to be accessible for technical
|
||||
reasons. Invoking a git subcommand as "git-xyzzy" from the command
|
||||
line has been deprecated since early 2006 (and officially announced in
|
||||
@@ -28,6 +28,16 @@ introduced in v1.5.2 and v1.4.4.5. If you want to keep your repositories
|
||||
backwards compatible past these versions, set repack.useDeltaBaseOffset
|
||||
to false or pack.indexVersion to 1, respectively.
|
||||
|
||||
We used to prevent sample hook scripts shipped in templates/ from
|
||||
triggering by default by relying on the fact that we install them as
|
||||
unexecutable, but on some filesystems, this approach does not work.
|
||||
They are now shipped with ".sample" suffix. If you want to activate
|
||||
any of these samples as-is, rename them to drop the ".sample" suffix,
|
||||
instead of running "chmod +x" on them. For example, you can rename
|
||||
hooks/post-update.sample to hooks/post-update to enable the sample
|
||||
hook that runs update-server-info, in order to make repositories
|
||||
friendly to dumb protocols (i.e. HTTP).
|
||||
|
||||
GIT_CONFIG, which was only documented as affecting "git config", but
|
||||
actually affected all git commands, now only affects "git config".
|
||||
GIT_LOCAL_CONFIG, also only documented as affecting "git config" and
|
||||
@@ -56,11 +66,7 @@ Updates since v1.5.6
|
||||
gangs.
|
||||
|
||||
* Sample hook scripts shipped in templates/ are now suffixed with
|
||||
*.sample. We used to prevent them from triggering by default by
|
||||
relying on the fact that we install them as unexecutable, but on
|
||||
some filesystems this approach does not work. Instead of running
|
||||
"chmod +x" on them, the users who want to activate these samples
|
||||
as-is can now rename them dropping *.sample suffix.
|
||||
*.sample.
|
||||
|
||||
* perl's in-place edit (-i) does not work well without backup files on Windows;
|
||||
some tests are rewritten to cope with this.
|
||||
@@ -172,7 +178,7 @@ Updates since v1.5.6
|
||||
* git-diff --check now checks leftover merge conflict markers.
|
||||
|
||||
* "git-diff -p" learned to grab a better hunk header lines in
|
||||
Pascal/Delphi and Ruby source files, and also pays attention to
|
||||
BibTex, Pascal/Delphi, and Ruby files and also pays attention to
|
||||
chapter and part boundary in TeX documents.
|
||||
|
||||
* When remote side used to have branch 'foo' and git-fetch finds that now
|
||||
@@ -186,7 +192,7 @@ Updates since v1.5.6
|
||||
|
||||
* fast-import and fast-export learned to export and import gitlinks.
|
||||
|
||||
* "gitk" left background process behind after begin asked to dig very deep
|
||||
* "gitk" left background process behind after being asked to dig very deep
|
||||
history and the user killed the UI; the process is killed when the UI goes
|
||||
away now.
|
||||
|
||||
@@ -239,15 +245,14 @@ Fixes since v1.5.6
|
||||
All of the fixes in v1.5.6 maintenance series are included in
|
||||
this release, unless otherwise noted.
|
||||
|
||||
* git-clone ignored its -u option; the fix needs to be backported to
|
||||
'maint';
|
||||
* git-clone ignored its -u option; the fix needs to be backported to
|
||||
'maint';
|
||||
|
||||
* git-mv used to lose the distinction between changes that are staged
|
||||
and that are only in the working tree, by staging both in the index
|
||||
after moving such a path.
|
||||
* git-mv used to lose the distinction between changes that are staged
|
||||
and that are only in the working tree, by staging both in the index
|
||||
after moving such a path.
|
||||
|
||||
* "git-rebase -i -p" rewrote the parents to wrong ones when amending
|
||||
(either edit or squash) was involved, and did not work correctly
|
||||
when fast forwarding.
|
||||
|
||||
---
|
||||
exec >/var/tmp/1
|
||||
O=v1.6.0-rc1-113-gf44bc33
|
||||
echo O=$(git describe refs/heads/master)
|
||||
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
|
||||
|
||||
@@ -978,6 +978,11 @@ pack.packSizeLimit::
|
||||
can be overridden by the `\--max-pack-size` option of
|
||||
linkgit:git-repack[1].
|
||||
|
||||
pager.<cmd>::
|
||||
Allows to set your own pager preferences for each command, overriding
|
||||
the default. If `\--pager` or `\--no-pager` is specified on the command
|
||||
line, it takes precedence over this option.
|
||||
|
||||
pull.octopus::
|
||||
The default merge strategy to use when pulling multiple branches
|
||||
at once.
|
||||
|
||||
@@ -10,7 +10,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git am' [--signoff] [--keep] [--utf8 | --no-utf8]
|
||||
[--3way] [--interactive] [--binary]
|
||||
[--3way] [--interactive]
|
||||
[--whitespace=<option>] [-C<n>] [-p<n>]
|
||||
[<mbox> | <Maildir>...]
|
||||
'git am' (--skip | --resolved | --abort)
|
||||
@@ -59,11 +59,6 @@ default. You could use `--no-utf8` to override this.
|
||||
it is supposed to apply to, and we have those blobs
|
||||
available locally.
|
||||
|
||||
-b::
|
||||
--binary::
|
||||
Pass `--allow-binary-replacement` flag to 'git-apply'
|
||||
(see linkgit:git-apply[1]).
|
||||
|
||||
--whitespace=<option>::
|
||||
This flag is passed to the 'git-apply' (see linkgit:git-apply[1])
|
||||
program that applies
|
||||
|
||||
@@ -16,12 +16,12 @@ This is usually not what an end user wants to run directly. See
|
||||
linkgit:git-commit[1] instead.
|
||||
|
||||
Creates a new commit object based on the provided tree object and
|
||||
emits the new commit object id on stdout. If no parent is given then
|
||||
it is considered to be an initial tree.
|
||||
emits the new commit object id on stdout.
|
||||
|
||||
A commit object usually has 1 parent (a commit after a change) or up
|
||||
to 16 parents. More than one parent represents a merge of branches
|
||||
that led to them.
|
||||
A commit object may have any number of parents. With exactly one
|
||||
parent, it is an ordinary commit. Having more than one parent makes
|
||||
the commit a merge between several lines of history. Initial (root)
|
||||
commits have no parents.
|
||||
|
||||
While a tree represents a particular directory state of a working
|
||||
directory, a commit represents that state in "time", and explains how
|
||||
|
||||
@@ -13,7 +13,7 @@ SYNOPSIS
|
||||
[--msg-filter <command>] [--commit-filter <command>]
|
||||
[--tag-name-filter <command>] [--subdirectory-filter <directory>]
|
||||
[--original <namespace>] [-d <directory>] [-f | --force]
|
||||
[<rev-list options>...]
|
||||
[--] [<rev-list options>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -168,10 +168,10 @@ to other tags will be rewritten to point to the underlying commit.
|
||||
'refs/original/', unless forced.
|
||||
|
||||
<rev-list options>...::
|
||||
When options are given after the new branch name, they will
|
||||
be passed to 'git-rev-list'. Only commits in the resulting
|
||||
output will be filtered, although the filtered commits can still
|
||||
reference parents which are outside of that set.
|
||||
Arguments for 'git-rev-list'. All positive refs included by
|
||||
these options are rewritten. You may also specify options
|
||||
such as '--all', but you must use '--' to separate them from
|
||||
the 'git-filter-branch' options.
|
||||
|
||||
|
||||
Examples
|
||||
@@ -196,6 +196,17 @@ git filter-branch --index-filter 'git rm --cached filename' HEAD
|
||||
|
||||
Now, you will get the rewritten history saved in HEAD.
|
||||
|
||||
To rewrite the repository to look as if `foodir/` had been its project
|
||||
root, and discard all other history:
|
||||
|
||||
-------------------------------------------------------
|
||||
git filter-branch --subdirectory-filter foodir -- --all
|
||||
-------------------------------------------------------
|
||||
|
||||
Thus you can, e.g., turn a library subdirectory into a repository of
|
||||
its own. Note the `\--` that separates 'filter-branch' options from
|
||||
revision options, and the `\--all` to rewrite all branches and tags.
|
||||
|
||||
To set a commit (which typically is at the tip of another
|
||||
history) to be the parent of the current initial commit, in
|
||||
order to paste the other history behind the current history:
|
||||
|
||||
@@ -147,9 +147,9 @@ include::diff-options.txt[]
|
||||
to any configured headers, and may be used multiple times.
|
||||
|
||||
--cover-letter::
|
||||
Generate a cover letter template. You still have to fill in
|
||||
a description, but the shortlog and the diffstat will be
|
||||
generated for you.
|
||||
In addition to the patches, generate a cover letter file
|
||||
containing the shortlog and the overall diffstat. You can
|
||||
fill in a description in the file before sending it out.
|
||||
|
||||
--suffix=.<sfx>::
|
||||
Instead of using `.patch` as the suffix for generated
|
||||
|
||||
@@ -31,8 +31,8 @@ OPTIONS
|
||||
operation. See the section <<URLS,GIT URLS>> below.
|
||||
|
||||
<refspec>...::
|
||||
The canonical format of each <refspec> parameter is
|
||||
`+?<src>:<dst>`; that is, an optional plus `+`, followed
|
||||
The canonical format of a <refspec> parameter is
|
||||
`+?<src>:<dst>`; that is, an optional plus `{plus}`, followed
|
||||
by the source ref, followed by a colon `:`, followed by
|
||||
the destination ref.
|
||||
+
|
||||
|
||||
@@ -90,15 +90,15 @@ One way to do it is to pull master into the topic branch:
|
||||
|
||||
The commits marked with `*` touch the same area in the same
|
||||
file; you need to resolve the conflicts when creating the commit
|
||||
marked with `+`. Then you can test the result to make sure your
|
||||
marked with `{plus}`. Then you can test the result to make sure your
|
||||
work-in-progress still works with what is in the latest master.
|
||||
|
||||
After this test merge, there are two ways to continue your work
|
||||
on the topic. The easiest is to build on top of the test merge
|
||||
commit `+`, and when your work in the topic branch is finally
|
||||
commit `{plus}`, and when your work in the topic branch is finally
|
||||
ready, pull the topic branch into master, and/or ask the
|
||||
upstream to pull from you. By that time, however, the master or
|
||||
the upstream might have been advanced since the test merge `+`,
|
||||
the upstream might have been advanced since the test merge `{plus}`,
|
||||
in which case the final commit graph would look like this:
|
||||
|
||||
------------
|
||||
|
||||
@@ -7,7 +7,7 @@ git-rm - Remove files from the working tree and from the index
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git rm' [-f] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
|
||||
'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -36,6 +36,7 @@ OPTIONS
|
||||
but this requires the `-r` option to be explicitly given.
|
||||
|
||||
-f::
|
||||
--force::
|
||||
Override the up-to-date check.
|
||||
|
||||
-n::
|
||||
|
||||
@@ -8,11 +8,13 @@ git-stash - Stash the changes in a dirty working directory away
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git stash' list
|
||||
'git stash' (show | apply | drop | pop ) [<stash>]
|
||||
'git stash' list [<options>]
|
||||
'git stash' (show | drop | pop ) [<stash>]
|
||||
'git stash' apply [--index] [<stash>]
|
||||
'git stash' branch <branchname> [<stash>]
|
||||
'git stash' [save [<message>]]
|
||||
'git stash' [save [--keep-index] [<message>]]
|
||||
'git stash' clear
|
||||
'git stash' create
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -116,6 +118,11 @@ pop [<stash>]::
|
||||
of the current working tree state. When no `<stash>` is given,
|
||||
`stash@\{0}` is assumed. See also `apply`.
|
||||
|
||||
create::
|
||||
|
||||
Create a stash (which is a regular commit object) and return its
|
||||
object name, without storing it anywhere in the ref namespace.
|
||||
|
||||
|
||||
DISCUSSION
|
||||
----------
|
||||
|
||||
@@ -138,6 +138,15 @@ and have no uncommitted changes.
|
||||
+
|
||||
--no-rebase;;
|
||||
After committing, do not rebase or reset.
|
||||
--commit-url <URL>;;
|
||||
Commit to this SVN URL (the full path). This is intended to
|
||||
allow existing git-svn repositories created with one transport
|
||||
method (e.g. `svn://` or `http://` for anonymous read) to be
|
||||
reused if a user is later given access to an alternate transport
|
||||
method (e.g. `svn+ssh://` or `https://`) for commit.
|
||||
|
||||
Using this option for any other purpose (don't ask)
|
||||
is very strongly discouraged.
|
||||
--
|
||||
|
||||
'log'::
|
||||
|
||||
@@ -43,6 +43,11 @@ unreleased) version of git, that is available from 'master'
|
||||
branch of the `git.git` repository.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v1.6.0/git.html[documentation for release 1.6.0]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.6.0.txt[1.6.0].
|
||||
|
||||
* link:v1.5.6.5/git.html[documentation for release 1.5.6.5]
|
||||
|
||||
* release notes for
|
||||
|
||||
@@ -307,9 +307,18 @@ backslash, and zero or more occurrences of `sub` followed by
|
||||
There are a few built-in patterns to make this easier, and `tex`
|
||||
is one of them, so you do not have to write the above in your
|
||||
configuration file (you still need to enable this with the
|
||||
attribute mechanism, via `.gitattributes`). Another built-in
|
||||
pattern is defined for `java` that defines a pattern suitable
|
||||
for program text in Java language.
|
||||
attribute mechanism, via `.gitattributes`). The following built in
|
||||
patterns are available:
|
||||
|
||||
- `bibtex` suitable for files with BibTeX coded references.
|
||||
|
||||
- `java` suitable for source code in the Java lanugage.
|
||||
|
||||
- `pascal` suitable for source code in the Pascal/Delphi language.
|
||||
|
||||
- `ruby` suitable for source code in the Ruby language.
|
||||
|
||||
- `tex` suitable for source code for LaTeX documents.
|
||||
|
||||
|
||||
Performing a three-way merge
|
||||
|
||||
@@ -1366,8 +1366,9 @@ your login shell is 'bash', only `.bashrc` is read and not
|
||||
|
||||
[NOTE]
|
||||
If you plan to publish this repository to be accessed over http,
|
||||
you should do `chmod +x my-git.git/hooks/post-update` at this
|
||||
point. This makes sure that every time you push into this
|
||||
you should do `mv my-git.git/hooks/post-update.sample
|
||||
my-git.git/hooks/post-update` at this point.
|
||||
This makes sure that every time you push into this
|
||||
repository, `git update-server-info` is run.
|
||||
|
||||
Your "public repository" is now ready to accept your changes.
|
||||
@@ -1486,11 +1487,11 @@ A recommended workflow for a "project lead" goes like this:
|
||||
If other people are pulling from your repository over dumb
|
||||
transport protocols (HTTP), you need to keep this repository
|
||||
'dumb transport friendly'. After `git init`,
|
||||
`$GIT_DIR/hooks/post-update` copied from the standard templates
|
||||
would contain a call to 'git-update-server-info' but the
|
||||
`post-update` hook itself is disabled by default -- enable it
|
||||
with `chmod +x post-update`. This makes sure 'git-update-server-info'
|
||||
keeps the necessary files up-to-date.
|
||||
`$GIT_DIR/hooks/post-update.sample` copied from the standard templates
|
||||
would contain a call to 'git-update-server-info'
|
||||
but you need to manually enable the hook with
|
||||
`mv post-update.sample post-update`. This makes sure
|
||||
'git-update-server-info' keeps the necessary files up-to-date.
|
||||
|
||||
3. Push into the public repository from your primary
|
||||
repository.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<refspec>::
|
||||
The canonical format of a <refspec> parameter is
|
||||
`+?<src>:<dst>`; that is, an optional plus `+`, followed
|
||||
`+?<src>:<dst>`; that is, an optional plus `{plus}`, followed
|
||||
by the source ref, followed by a colon `:`, followed by
|
||||
the destination ref.
|
||||
+
|
||||
|
||||
@@ -43,11 +43,13 @@ endif::git-rev-list[]
|
||||
|
||||
--parents::
|
||||
|
||||
Print the parents of the commit.
|
||||
Print the parents of the commit. Also enables parent
|
||||
rewriting, see 'History Simplification' below.
|
||||
|
||||
--children::
|
||||
|
||||
Print the children of the commit.
|
||||
Print the children of the commit. Also enables parent
|
||||
rewriting, see 'History Simplification' below.
|
||||
|
||||
ifdef::git-rev-list[]
|
||||
--timestamp::
|
||||
@@ -71,7 +73,7 @@ For example, if you have this topology:
|
||||
o---x---a---a branch A
|
||||
-----------------------------------------------------------------------
|
||||
+
|
||||
you would get an output line this:
|
||||
you would get an output like this:
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
$ git rev-list --left-right --boundary --pretty=oneline A...B
|
||||
@@ -94,6 +96,7 @@ you would get an output line this:
|
||||
This implies the '--topo-order' option by default, but the
|
||||
'--date-order' option may also be specified.
|
||||
|
||||
ifndef::git-rev-list[]
|
||||
Diff Formatting
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -123,6 +126,7 @@ options may be given. See linkgit:git-diff-files[1] for more options.
|
||||
-t::
|
||||
|
||||
Show the tree objects in the diff output. This implies '-r'.
|
||||
endif::git-rev-list[]
|
||||
|
||||
Commit Limiting
|
||||
~~~~~~~~~~~~~~~
|
||||
@@ -191,14 +195,6 @@ endif::git-rev-list[]
|
||||
|
||||
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.
|
||||
@@ -264,11 +260,10 @@ 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
|
||||
'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'.
|
||||
This option cannot be combined with '\--reverse'.
|
||||
See also linkgit:git-reflog[1].
|
||||
|
||||
--merge::
|
||||
@@ -281,18 +276,144 @@ See also linkgit:git-reflog[1].
|
||||
Output uninteresting commits at the boundary, which are usually
|
||||
not shown.
|
||||
|
||||
--
|
||||
|
||||
History Simplification
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When optional paths are given, 'git-rev-list' simplifies commits with
|
||||
various strategies, according to the options you have selected.
|
||||
|
||||
Suppose you specified `foo` as the <paths>. We shall call commits
|
||||
that modify `foo` !TREESAME, and the rest TREESAME. (In a diff
|
||||
filtered for `foo`, they look different and equal, respectively.)
|
||||
|
||||
In the following, we will always refer to the same example history to
|
||||
illustrate the differences between simplification settings. We assume
|
||||
that you are filtering for a file `foo` in this commit graph:
|
||||
-----------------------------------------------------------------------
|
||||
.-A---M---N---O---P
|
||||
/ / / / /
|
||||
I B C D E
|
||||
\ / / / /
|
||||
`-------------'
|
||||
-----------------------------------------------------------------------
|
||||
The horizontal line of history A--P is taken to be the first parent of
|
||||
each merge. The commits are:
|
||||
|
||||
* `I` is the initial commit, in which `foo` exists with contents
|
||||
"asdf", and a file `quux` exists with contents "quux". Initial
|
||||
commits are compared to an empty tree, so `I` is !TREESAME.
|
||||
|
||||
* In `A`, `foo` contains just "foo".
|
||||
|
||||
* `B` contains the same change as `A`. Its merge `M` is trivial and
|
||||
hence TREESAME to all parents.
|
||||
|
||||
* `C` does not change `foo`, but its merge `N` changes it to "foobar",
|
||||
so it is not TREESAME to any parent.
|
||||
|
||||
* `D` sets `foo` to "baz". Its merge `O` combines the strings from
|
||||
`N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent.
|
||||
|
||||
* `E` changes `quux` to "xyzzy", and its merge `P` combines the
|
||||
strings to "quux xyzzy". Despite appearing interesting, `P` is
|
||||
TREESAME to all parents.
|
||||
|
||||
'rev-list' walks backwards through history, including or excluding
|
||||
commits based on whether '\--full-history' and/or parent rewriting
|
||||
(via '\--parents' or '\--children') are used. The following settings
|
||||
are available.
|
||||
|
||||
Default mode::
|
||||
|
||||
Commits are included if they are not TREESAME to any parent
|
||||
(though this can be changed, see '\--sparse' below). If the
|
||||
commit was a merge, and it was TREESAME to one parent, follow
|
||||
only that parent. (Even if there are several TREESAME
|
||||
parents, follow only one of them.) Otherwise, follow all
|
||||
parents.
|
||||
+
|
||||
This results in:
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
.-A---N---O
|
||||
/ /
|
||||
I---------D
|
||||
-----------------------------------------------------------------------
|
||||
+
|
||||
Note how the rule to only follow the TREESAME parent, if one is
|
||||
available, removed `B` from consideration entirely. `C` was
|
||||
considered via `N`, but is TREESAME. Root commits are compared to an
|
||||
empty tree, so `I` is !TREESAME.
|
||||
+
|
||||
Parent/child relations are only visible with --parents, but that does
|
||||
not affect the commits selected in default mode, so we have shown the
|
||||
parent lines.
|
||||
|
||||
--full-history without parent rewriting::
|
||||
|
||||
This mode differs from the default in one point: always follow
|
||||
all parents of a merge, even if it is TREESAME to one of them.
|
||||
Even if more than one side of the merge has commits that are
|
||||
included, this does not imply that the merge itself is! In
|
||||
the example, we get
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
I A B N D O
|
||||
-----------------------------------------------------------------------
|
||||
+
|
||||
`P` and `M` were excluded because they are TREESAME to a parent. `E`,
|
||||
`C` and `B` were all walked, but only `B` was !TREESAME, so the others
|
||||
do not appear.
|
||||
+
|
||||
Note that without parent rewriting, it is not really possible to talk
|
||||
about the parent/child relationships between the commits, so we show
|
||||
them disconnected.
|
||||
|
||||
--full-history with parent rewriting::
|
||||
|
||||
Ordinary commits are only included if they are !TREESAME
|
||||
(though this can be changed, see '\--sparse' below).
|
||||
+
|
||||
Merges are always included. However, their parent list is rewritten:
|
||||
Along each parent, prune away commits that are not included
|
||||
themselves. This results in
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
.-A---M---N---O---P
|
||||
/ / / / /
|
||||
I B / D /
|
||||
\ / / / /
|
||||
`-------------'
|
||||
-----------------------------------------------------------------------
|
||||
+
|
||||
Compare to '\--full-history' without rewriting above. Note that `E`
|
||||
was pruned away because it is TREESAME, but the parent list of P was
|
||||
rewritten to contain `E`'s parent `I`. The same happened for `C` and
|
||||
`N`. Note also that `P` was included despite being TREESAME.
|
||||
|
||||
In addition to the above settings, you can change whether TREESAME
|
||||
affects inclusion:
|
||||
|
||||
--dense::
|
||||
|
||||
Commits that are walked are included if they are not TREESAME
|
||||
to any parent.
|
||||
|
||||
--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.
|
||||
All commits that are walked are included.
|
||||
+
|
||||
Note that without '\--full-history', this still simplifies merges: if
|
||||
one of the parents is TREESAME, we follow only that one, so the other
|
||||
sides of the merge are never walked.
|
||||
|
||||
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[]
|
||||
Bisection Helpers
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
--bisect::
|
||||
|
||||
Limit output to the one commit object which is roughly halfway between
|
||||
@@ -342,7 +463,6 @@ 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
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1128,8 +1128,8 @@ This typically includes files generated by a build process or temporary
|
||||
backup files made by your editor. Of course, 'not' tracking files with git
|
||||
is just a matter of 'not' calling "`git-add`" on them. But it quickly becomes
|
||||
annoying to have these untracked files lying around; e.g. they make
|
||||
"`git add .`" and "`git commit -a`" practically useless, and they keep
|
||||
showing up in the output of "`git status`".
|
||||
"`git add .`" practically useless, and they keep showing up in the output of
|
||||
"`git status`".
|
||||
|
||||
You can tell git to ignore certain files by creating a file called .gitignore
|
||||
in the top level of your working directory, with contents such as:
|
||||
@@ -1890,7 +1890,7 @@ adjustments to give web clients some extra information they need:
|
||||
$ mv proj.git /home/you/public_html/proj.git
|
||||
$ cd proj.git
|
||||
$ git --bare update-server-info
|
||||
$ chmod a+x hooks/post-update
|
||||
$ mv hooks/post-update.sample hooks/post-update
|
||||
-------------------------------------------------
|
||||
|
||||
(For an explanation of the last two lines, see
|
||||
@@ -2825,8 +2825,8 @@ You can also add a "+" to force the update each time:
|
||||
$ git config remote.example.fetch +master:ref/remotes/example/master
|
||||
-------------------------------------------------
|
||||
|
||||
Don't do this unless you're sure you won't mind "git-fetch" possibly
|
||||
throwing away commits on mybranch.
|
||||
Don't do this unless you're sure you won't mind "git fetch" possibly
|
||||
throwing away commits on 'example/master'.
|
||||
|
||||
Also note that all of the above configuration can be performed by
|
||||
directly editing the file .git/config instead of using
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.5.6.GIT
|
||||
DEF_VER=v1.6.0.GIT
|
||||
|
||||
LF='
|
||||
'
|
||||
@@ -16,6 +16,7 @@ elif test -d .git -o -f .git &&
|
||||
case "$VN" in
|
||||
*$LF*) (exit 1) ;;
|
||||
v[0-9]*)
|
||||
git update-index -q --refresh
|
||||
test -z "$(git diff-index --name-only HEAD --)" ||
|
||||
VN="$VN-dirty" ;;
|
||||
esac
|
||||
|
||||
12
Makefile
12
Makefile
@@ -1060,9 +1060,11 @@ export TAR INSTALL DESTDIR SHELL_PATH
|
||||
|
||||
### Build rules
|
||||
|
||||
all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
|
||||
SHELL = $(SHELL_PATH)
|
||||
|
||||
all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
|
||||
ifneq (,$X)
|
||||
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';)
|
||||
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
|
||||
endif
|
||||
|
||||
all::
|
||||
@@ -1073,6 +1075,11 @@ endif
|
||||
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all
|
||||
$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1)
|
||||
|
||||
please_set_SHELL_PATH_to_a_more_modern_shell:
|
||||
@$$(:)
|
||||
|
||||
shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
|
||||
strip: $(PROGRAMS) git$X
|
||||
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
|
||||
|
||||
@@ -1455,6 +1462,7 @@ endif
|
||||
$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
|
||||
|
||||
.PHONY: all install clean strip
|
||||
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS
|
||||
.PHONY: .FORCE-GIT-BUILD-OPTIONS
|
||||
|
||||
|
||||
@@ -330,7 +330,8 @@ static struct ref *write_remote_refs(const struct ref *refs,
|
||||
struct ref *r;
|
||||
|
||||
get_fetch_map(refs, refspec, &tail, 0);
|
||||
get_fetch_map(refs, tag_refspec, &tail, 0);
|
||||
if (!option_mirror)
|
||||
get_fetch_map(refs, tag_refspec, &tail, 0);
|
||||
|
||||
for (r = local_refs; r; r = r->next)
|
||||
add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
|
||||
|
||||
@@ -203,7 +203,8 @@ static void handle_content_transfer_encoding(const struct strbuf *line)
|
||||
|
||||
static int is_multipart_boundary(const struct strbuf *line)
|
||||
{
|
||||
return !strbuf_cmp(line, *content_top);
|
||||
return (((*content_top)->len <= line->len) &&
|
||||
!memcmp(line->buf, (*content_top)->buf, (*content_top)->len));
|
||||
}
|
||||
|
||||
static void cleanup_subject(struct strbuf *subject)
|
||||
@@ -649,8 +650,11 @@ again:
|
||||
check_header(&line, p_hdr_data, 0);
|
||||
|
||||
strbuf_release(&newline);
|
||||
/* eat the blank line after section info */
|
||||
return (strbuf_getline(&line, fin, '\n') == 0);
|
||||
/* replenish line */
|
||||
if (strbuf_getline(&line, fin, '\n'))
|
||||
return 0;
|
||||
strbuf_addch(&line, '\n');
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int patchbreak(const struct strbuf *line)
|
||||
@@ -757,9 +761,10 @@ static void handle_body(void)
|
||||
/* process any boundary lines */
|
||||
if (*content_top && is_multipart_boundary(&line)) {
|
||||
/* flush any leftover */
|
||||
if (line.len)
|
||||
handle_filter(&line);
|
||||
|
||||
if (prev.len) {
|
||||
handle_filter(&prev);
|
||||
strbuf_reset(&prev);
|
||||
}
|
||||
if (!handle_boundary())
|
||||
goto handle_body_out;
|
||||
}
|
||||
|
||||
@@ -604,8 +604,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dwim_ref(argv[i], spec - argv[i], sha1, &ref)) {
|
||||
status |= error("%s points nowhere!", argv[i]);
|
||||
if (!dwim_log(argv[i], spec - argv[i], sha1, &ref)) {
|
||||
status |= error("no reflog for '%s'", argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ static struct option builtin_rm_options[] = {
|
||||
OPT__DRY_RUN(&show_only),
|
||||
OPT__QUIET(&quiet),
|
||||
OPT_BOOLEAN( 0 , "cached", &index_only, "only remove from the index"),
|
||||
OPT_BOOLEAN('f', NULL, &force, "override the up-to-date check"),
|
||||
OPT_BOOLEAN('f', "force", &force, "override the up-to-date check"),
|
||||
OPT_BOOLEAN('r', NULL, &recursive, "allow recursive removal"),
|
||||
OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
|
||||
"exit with a zero status even if nothing matched"),
|
||||
|
||||
@@ -501,7 +501,7 @@ __git_has_doubledash ()
|
||||
return 1
|
||||
}
|
||||
|
||||
__git_whitespacelist="nowarn warn error error-all strip"
|
||||
__git_whitespacelist="nowarn warn error error-all fix"
|
||||
|
||||
_git_am ()
|
||||
{
|
||||
@@ -885,7 +885,11 @@ _git_help ()
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__gitcomp "$(__git_all_commands)"
|
||||
__gitcomp "$(__git_all_commands)
|
||||
attributes cli core-tutorial cvs-migration
|
||||
diffcore gitk glossary hooks ignore modules
|
||||
repository-layout tutorial tutorial-2
|
||||
"
|
||||
}
|
||||
|
||||
_git_init ()
|
||||
@@ -972,6 +976,7 @@ _git_log ()
|
||||
--decorate --diff-filter=
|
||||
--color-words --walk-reflogs
|
||||
--parents --children --full-history
|
||||
--merge
|
||||
"
|
||||
return
|
||||
;;
|
||||
@@ -1001,6 +1006,25 @@ _git_merge ()
|
||||
__gitcomp "$(__git_refs)"
|
||||
}
|
||||
|
||||
_git_mergetool ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--tool=*)
|
||||
__gitcomp "
|
||||
kdiff3 tkdiff meld xxdiff emerge
|
||||
vimdiff gvimdiff ecmerge opendiff
|
||||
" "" "${cur##--tool=}"
|
||||
return
|
||||
;;
|
||||
--*)
|
||||
__gitcomp "--tool="
|
||||
return
|
||||
;;
|
||||
esac
|
||||
COMPREPLY=()
|
||||
}
|
||||
|
||||
_git_merge_base ()
|
||||
{
|
||||
__gitcomp "$(__git_refs)"
|
||||
@@ -1439,7 +1463,7 @@ _git_stash ()
|
||||
apply,--*)
|
||||
__gitcomp "--index"
|
||||
;;
|
||||
show,--*|apply,--*|drop,--*|pop,--*|branch,--*)
|
||||
show,--*|drop,--*|pop,--*|branch,--*)
|
||||
COMPREPLY=()
|
||||
;;
|
||||
show,*|apply,*|drop,*|pop,*|branch,*)
|
||||
@@ -1650,6 +1674,7 @@ _git ()
|
||||
ls-remote) _git_ls_remote ;;
|
||||
ls-tree) _git_ls_tree ;;
|
||||
merge) _git_merge;;
|
||||
mergetool) _git_mergetool;;
|
||||
merge-base) _git_merge_base ;;
|
||||
mv) _git_mv ;;
|
||||
name-rev) _git_name_rev ;;
|
||||
|
||||
@@ -16,6 +16,46 @@ from sets import Set;
|
||||
|
||||
verbose = False
|
||||
|
||||
|
||||
def p4_build_cmd(cmd):
|
||||
"""Build a suitable p4 command line.
|
||||
|
||||
This consolidates building and returning a p4 command line into one
|
||||
location. It means that hooking into the environment, or other configuration
|
||||
can be done more easily.
|
||||
"""
|
||||
real_cmd = "%s " % "p4"
|
||||
|
||||
user = gitConfig("git-p4.user")
|
||||
if len(user) > 0:
|
||||
real_cmd += "-u %s " % user
|
||||
|
||||
password = gitConfig("git-p4.password")
|
||||
if len(password) > 0:
|
||||
real_cmd += "-P %s " % password
|
||||
|
||||
port = gitConfig("git-p4.port")
|
||||
if len(port) > 0:
|
||||
real_cmd += "-p %s " % port
|
||||
|
||||
host = gitConfig("git-p4.host")
|
||||
if len(host) > 0:
|
||||
real_cmd += "-h %s " % host
|
||||
|
||||
client = gitConfig("git-p4.client")
|
||||
if len(client) > 0:
|
||||
real_cmd += "-c %s " % client
|
||||
|
||||
real_cmd += "%s" % (cmd)
|
||||
if verbose:
|
||||
print real_cmd
|
||||
return real_cmd
|
||||
|
||||
def chdir(dir):
|
||||
if os.name == 'nt':
|
||||
os.environ['PWD']=dir
|
||||
os.chdir(dir)
|
||||
|
||||
def die(msg):
|
||||
if verbose:
|
||||
raise Exception(msg)
|
||||
@@ -34,6 +74,10 @@ def write_pipe(c, str):
|
||||
|
||||
return val
|
||||
|
||||
def p4_write_pipe(c, str):
|
||||
real_cmd = p4_build_cmd(c)
|
||||
return write_pipe(c, str)
|
||||
|
||||
def read_pipe(c, ignore_error=False):
|
||||
if verbose:
|
||||
sys.stderr.write('Reading pipe: %s\n' % c)
|
||||
@@ -45,6 +89,9 @@ def read_pipe(c, ignore_error=False):
|
||||
|
||||
return val
|
||||
|
||||
def p4_read_pipe(c, ignore_error=False):
|
||||
real_cmd = p4_build_cmd(c)
|
||||
return read_pipe(real_cmd, ignore_error)
|
||||
|
||||
def read_pipe_lines(c):
|
||||
if verbose:
|
||||
@@ -57,12 +104,22 @@ def read_pipe_lines(c):
|
||||
|
||||
return val
|
||||
|
||||
def p4_read_pipe_lines(c):
|
||||
"""Specifically invoke p4 on the command supplied. """
|
||||
real_cmd = p4_build_cmd(c)
|
||||
return read_pipe_lines(real_cmd)
|
||||
|
||||
def system(cmd):
|
||||
if verbose:
|
||||
sys.stderr.write("executing %s\n" % cmd)
|
||||
if os.system(cmd) != 0:
|
||||
die("command failed: %s" % cmd)
|
||||
|
||||
def p4_system(cmd):
|
||||
"""Specifically invoke p4 as the system command. """
|
||||
real_cmd = p4_build_cmd(cmd)
|
||||
return system(real_cmd)
|
||||
|
||||
def isP4Exec(kind):
|
||||
"""Determine if a Perforce 'kind' should have execute permission
|
||||
|
||||
@@ -84,12 +141,12 @@ def setP4ExecBit(file, mode):
|
||||
if p4Type[-1] == "+":
|
||||
p4Type = p4Type[0:-1]
|
||||
|
||||
system("p4 reopen -t %s %s" % (p4Type, file))
|
||||
p4_system("reopen -t %s %s" % (p4Type, file))
|
||||
|
||||
def getP4OpenedType(file):
|
||||
# Returns the perforce file type for the given file.
|
||||
|
||||
result = read_pipe("p4 opened %s" % file)
|
||||
result = p4_read_pipe("opened %s" % file)
|
||||
match = re.match(".*\((.+)\)\r?$", result)
|
||||
if match:
|
||||
return match.group(1)
|
||||
@@ -145,7 +202,7 @@ def isModeExecChanged(src_mode, dst_mode):
|
||||
return isModeExec(src_mode) != isModeExec(dst_mode)
|
||||
|
||||
def p4CmdList(cmd, stdin=None, stdin_mode='w+b'):
|
||||
cmd = "p4 -G %s" % cmd
|
||||
cmd = p4_build_cmd("-G %s" % (cmd))
|
||||
if verbose:
|
||||
sys.stderr.write("Opening pipe: %s\n" % cmd)
|
||||
|
||||
@@ -364,7 +421,7 @@ def originP4BranchesExist():
|
||||
|
||||
def p4ChangesForPaths(depotPaths, changeRange):
|
||||
assert depotPaths
|
||||
output = read_pipe_lines("p4 changes " + ' '.join (["%s...%s" % (p, changeRange)
|
||||
output = p4_read_pipe_lines("changes " + ' '.join (["%s...%s" % (p, changeRange)
|
||||
for p in depotPaths]))
|
||||
|
||||
changes = []
|
||||
@@ -512,7 +569,7 @@ class P4Submit(Command):
|
||||
# remove lines in the Files section that show changes to files outside the depot path we're committing into
|
||||
template = ""
|
||||
inFilesSection = False
|
||||
for line in read_pipe_lines("p4 change -o"):
|
||||
for line in p4_read_pipe_lines("change -o"):
|
||||
if line.endswith("\r\n"):
|
||||
line = line[:-2] + "\n"
|
||||
if inFilesSection:
|
||||
@@ -547,7 +604,7 @@ class P4Submit(Command):
|
||||
modifier = diff['status']
|
||||
path = diff['src']
|
||||
if modifier == "M":
|
||||
system("p4 edit \"%s\"" % path)
|
||||
p4_system("edit \"%s\"" % path)
|
||||
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
|
||||
filesToChangeExecBit[path] = diff['dst_mode']
|
||||
editedFiles.add(path)
|
||||
@@ -562,8 +619,8 @@ class P4Submit(Command):
|
||||
filesToAdd.remove(path)
|
||||
elif modifier == "R":
|
||||
src, dest = diff['src'], diff['dst']
|
||||
system("p4 integrate -Dt \"%s\" \"%s\"" % (src, dest))
|
||||
system("p4 edit \"%s\"" % (dest))
|
||||
p4_system("integrate -Dt \"%s\" \"%s\"" % (src, dest))
|
||||
p4_system("edit \"%s\"" % (dest))
|
||||
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
|
||||
filesToChangeExecBit[dest] = diff['dst_mode']
|
||||
os.unlink(dest)
|
||||
@@ -587,7 +644,7 @@ class P4Submit(Command):
|
||||
if response == "s":
|
||||
print "Skipping! Good luck with the next patches..."
|
||||
for f in editedFiles:
|
||||
system("p4 revert \"%s\"" % f);
|
||||
p4_system("revert \"%s\"" % f);
|
||||
for f in filesToAdd:
|
||||
system("rm %s" %f)
|
||||
return
|
||||
@@ -610,10 +667,10 @@ class P4Submit(Command):
|
||||
system(applyPatchCmd)
|
||||
|
||||
for f in filesToAdd:
|
||||
system("p4 add \"%s\"" % f)
|
||||
p4_system("add \"%s\"" % f)
|
||||
for f in filesToDelete:
|
||||
system("p4 revert \"%s\"" % f)
|
||||
system("p4 delete \"%s\"" % f)
|
||||
p4_system("revert \"%s\"" % f)
|
||||
p4_system("delete \"%s\"" % f)
|
||||
|
||||
# Set/clear executable bits
|
||||
for f in filesToChangeExecBit.keys():
|
||||
@@ -629,7 +686,7 @@ class P4Submit(Command):
|
||||
submitTemplate = self.prepareLogMessage(template, logMessage)
|
||||
if os.environ.has_key("P4DIFF"):
|
||||
del(os.environ["P4DIFF"])
|
||||
diff = read_pipe("p4 diff -du ...")
|
||||
diff = p4_read_pipe("diff -du ...")
|
||||
|
||||
newdiff = ""
|
||||
for newFile in filesToAdd:
|
||||
@@ -667,7 +724,7 @@ class P4Submit(Command):
|
||||
if self.isWindows:
|
||||
submitTemplate = submitTemplate.replace("\r\n", "\n")
|
||||
|
||||
write_pipe("p4 submit -i", submitTemplate)
|
||||
p4_write_pipe("submit -i", submitTemplate)
|
||||
else:
|
||||
fileName = "submit.txt"
|
||||
file = open(fileName, "w+")
|
||||
@@ -712,9 +769,9 @@ class P4Submit(Command):
|
||||
print "Perforce checkout for depot path %s located at %s" % (self.depotPath, self.clientPath)
|
||||
self.oldWorkingDirectory = os.getcwd()
|
||||
|
||||
os.chdir(self.clientPath)
|
||||
chdir(self.clientPath)
|
||||
print "Syncronizing p4 checkout..."
|
||||
system("p4 sync ...")
|
||||
p4_system("sync ...")
|
||||
|
||||
self.check()
|
||||
|
||||
@@ -732,7 +789,7 @@ class P4Submit(Command):
|
||||
|
||||
if len(commits) == 0:
|
||||
print "All changes applied!"
|
||||
os.chdir(self.oldWorkingDirectory)
|
||||
chdir(self.oldWorkingDirectory)
|
||||
|
||||
sync = P4Sync()
|
||||
sync.run([])
|
||||
@@ -1399,7 +1456,7 @@ class P4Sync(Command):
|
||||
if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch):
|
||||
system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch))
|
||||
|
||||
if self.useClientSpec or gitConfig("p4.useclientspec") == "true":
|
||||
if self.useClientSpec or gitConfig("git-p4.useclientspec") == "true":
|
||||
self.getClientSpec()
|
||||
|
||||
# TODO: should always look at previous commits,
|
||||
@@ -1670,7 +1727,7 @@ class P4Clone(P4Sync):
|
||||
print "Importing from %s into %s" % (', '.join(depotPaths), self.cloneDestination)
|
||||
if not os.path.exists(self.cloneDestination):
|
||||
os.makedirs(self.cloneDestination)
|
||||
os.chdir(self.cloneDestination)
|
||||
chdir(self.cloneDestination)
|
||||
system("git init")
|
||||
self.gitdir = os.getcwd() + "/.git"
|
||||
if not P4Sync.run(self, depotPaths):
|
||||
@@ -1782,7 +1839,7 @@ def main():
|
||||
if os.path.exists(cmd.gitdir):
|
||||
cdup = read_pipe("git rev-parse --show-cdup").strip()
|
||||
if len(cdup) > 0:
|
||||
os.chdir(cdup);
|
||||
chdir(cdup);
|
||||
|
||||
if not isValidGitDir(cmd.gitdir):
|
||||
if isValidGitDir(cmd.gitdir + "/.git"):
|
||||
|
||||
@@ -63,18 +63,6 @@ It is recommended to run 'git repack -a -d -f' from time to time when using
|
||||
incremental imports to optimally combine the individual git packs that each
|
||||
incremental import creates through the use of git-fast-import.
|
||||
|
||||
|
||||
A useful setup may be that you have a periodically updated git repository
|
||||
somewhere that contains a complete import of a Perforce project. That git
|
||||
repository can be used to clone the working repository from and one would
|
||||
import from Perforce directly after cloning using git-p4. If the connection to
|
||||
the Perforce server is slow and the working repository hasn't been synced for a
|
||||
while it may be desirable to fetch changes from the origin git repository using
|
||||
the efficient git protocol. git-p4 supports this setup by calling "git fetch origin"
|
||||
by default if there is an origin branch. You can disable this using
|
||||
|
||||
git config git-p4.syncFromOrigin false
|
||||
|
||||
Updating
|
||||
========
|
||||
|
||||
@@ -140,6 +128,62 @@ Example
|
||||
git-p4 rebase
|
||||
|
||||
|
||||
Configuration parameters
|
||||
========================
|
||||
|
||||
git-p4.user ($P4USER)
|
||||
|
||||
Allows you to specify the username to use to connect to the Perforce repository.
|
||||
|
||||
git config [--global] git-p4.user public
|
||||
|
||||
git-p4.password ($P4PASS)
|
||||
|
||||
Allows you to specify the password to use to connect to the Perforce repository.
|
||||
Warning this password will be visible on the command-line invocation of the p4 binary.
|
||||
|
||||
git config [--global] git-p4.password public1234
|
||||
|
||||
git-p4.port ($P4PORT)
|
||||
|
||||
Specify the port to be used to contact the Perforce server. As this will be passed
|
||||
directly to the p4 binary, it may be in the format host:port as well.
|
||||
|
||||
git config [--global] git-p4.port codes.zimbra.com:2666
|
||||
|
||||
git-p4.host ($P4HOST)
|
||||
|
||||
Specify the host to contact for a Perforce repository.
|
||||
|
||||
git config [--global] git-p4.host perforce.example.com
|
||||
|
||||
git-p4.client ($P4CLIENT)
|
||||
|
||||
Specify the client name to use
|
||||
|
||||
git config [--global] git-p4.client public-view
|
||||
|
||||
git-p4.allowSubmit
|
||||
|
||||
git config [--global] git-p4.allowSubmit false
|
||||
|
||||
git-p4.syncFromOrigin
|
||||
|
||||
A useful setup may be that you have a periodically updated git repository
|
||||
somewhere that contains a complete import of a Perforce project. That git
|
||||
repository can be used to clone the working repository from and one would
|
||||
import from Perforce directly after cloning using git-p4. If the connection to
|
||||
the Perforce server is slow and the working repository hasn't been synced for a
|
||||
while it may be desirable to fetch changes from the origin git repository using
|
||||
the efficient git protocol. git-p4 supports this setup by calling "git fetch origin"
|
||||
by default if there is an origin branch. You can disable this using:
|
||||
|
||||
git config [--global] git-p4.syncFromOrigin false
|
||||
|
||||
git-p4.useclientspec
|
||||
|
||||
git config [--global] git-p4.useclientspec false
|
||||
|
||||
Implementation Details...
|
||||
=========================
|
||||
|
||||
|
||||
1
daemon.c
1
daemon.c
@@ -794,6 +794,7 @@ static void child_handler(int signo)
|
||||
}
|
||||
break;
|
||||
}
|
||||
signal(SIGCHLD, child_handler);
|
||||
}
|
||||
|
||||
static int set_reuse_addr(int sockfd)
|
||||
|
||||
4
diff.c
4
diff.c
@@ -1387,6 +1387,7 @@ static struct builtin_funcname_pattern {
|
||||
"\\|"
|
||||
"^\\(.*=[ \t]*\\(class\\|record\\).*\\)$"
|
||||
},
|
||||
{ "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" },
|
||||
{ "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" },
|
||||
{ "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" },
|
||||
};
|
||||
@@ -1631,7 +1632,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
ecb.priv = &data;
|
||||
xdi_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
|
||||
|
||||
if (data.trailing_blanks_start) {
|
||||
if ((data.ws_rule & WS_TRAILING_SPACE) &&
|
||||
data.trailing_blanks_start) {
|
||||
fprintf(o->file, "%s:%d: ends with blank lines.\n",
|
||||
data.filename, data.trailing_blanks_start);
|
||||
data.status = 1; /* report errors */
|
||||
|
||||
2
dir.c
2
dir.c
@@ -54,7 +54,7 @@ int common_prefix(const char **pathspec)
|
||||
|
||||
static inline int special_char(unsigned char c1)
|
||||
{
|
||||
return !c1 || c1 == '*' || c1 == '[' || c1 == '?';
|
||||
return !c1 || c1 == '*' || c1 == '[' || c1 == '?' || c1 == '\\';
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
19
git-am.sh
19
git-am.sh
@@ -10,7 +10,7 @@ git am [options] (--resolved | --skip | --abort)
|
||||
--
|
||||
d,dotest= (removed -- do not use)
|
||||
i,interactive run interactively
|
||||
b,binary pass --allow-binary-replacement to git-apply
|
||||
b,binary (historical option -- no-op)
|
||||
3,3way allow fall back on 3way merging if needed
|
||||
s,signoff add a Signed-off-by line to the commit message
|
||||
u,utf8 recode into utf8 (default)
|
||||
@@ -87,7 +87,7 @@ fall_back_3way () {
|
||||
|
||||
echo Using index info to reconstruct a base tree...
|
||||
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
git apply $binary --cached <"$dotest/patch"
|
||||
git apply --cached <"$dotest/patch"
|
||||
then
|
||||
mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
|
||||
mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
|
||||
@@ -121,7 +121,7 @@ It does not apply to blobs recorded in its index."
|
||||
|
||||
prec=4
|
||||
dotest="$GIT_DIR/rebase-apply"
|
||||
sign= utf8=t keep= skip= interactive= resolved= binary= rebasing= abort=
|
||||
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
|
||||
resolvemsg= resume=
|
||||
git_apply_opt=
|
||||
|
||||
@@ -131,7 +131,7 @@ do
|
||||
-i|--interactive)
|
||||
interactive=t ;;
|
||||
-b|--binary)
|
||||
binary=t ;;
|
||||
: ;;
|
||||
-3|--3way)
|
||||
threeway=t ;;
|
||||
-s|--signoff)
|
||||
@@ -149,7 +149,7 @@ do
|
||||
--abort)
|
||||
abort=t ;;
|
||||
--rebasing)
|
||||
rebasing=t threeway=t keep=t binary=t ;;
|
||||
rebasing=t threeway=t keep=t ;;
|
||||
-d|--dotest)
|
||||
die "-d option is no longer supported. Do not use."
|
||||
;;
|
||||
@@ -247,10 +247,9 @@ else
|
||||
exit 1
|
||||
}
|
||||
|
||||
# -b, -s, -u, -k and --whitespace flags are kept for the
|
||||
# -s, -u, -k and --whitespace flags are kept for the
|
||||
# resuming session after a patch failure.
|
||||
# -3 and -i can and must be given when resuming.
|
||||
echo "$binary" >"$dotest/binary"
|
||||
echo " $ws" >"$dotest/whitespace"
|
||||
echo "$sign" >"$dotest/sign"
|
||||
echo "$utf8" >"$dotest/utf8"
|
||||
@@ -274,10 +273,6 @@ case "$resolved" in
|
||||
fi
|
||||
esac
|
||||
|
||||
if test "$(cat "$dotest/binary")" = t
|
||||
then
|
||||
binary=--allow-binary-replacement
|
||||
fi
|
||||
if test "$(cat "$dotest/utf8")" = t
|
||||
then
|
||||
utf8=-u
|
||||
@@ -459,7 +454,7 @@ do
|
||||
|
||||
case "$resolved" in
|
||||
'')
|
||||
git apply $git_apply_opt $binary --index "$dotest/patch"
|
||||
git apply $git_apply_opt --index "$dotest/patch"
|
||||
apply_status=$?
|
||||
;;
|
||||
t)
|
||||
|
||||
@@ -220,7 +220,8 @@ bisect_next_check() {
|
||||
if test -t 0
|
||||
then
|
||||
printf >&2 'Are you sure [Y/n]? '
|
||||
case "$(read yesno)" in [Nn]*) exit 1 ;; esac
|
||||
read yesno
|
||||
case "$yesno" in [Nn]*) exit 1 ;; esac
|
||||
fi
|
||||
: bisect without good...
|
||||
;;
|
||||
|
||||
@@ -361,9 +361,17 @@ do
|
||||
;;
|
||||
$_x40)
|
||||
echo "Ref '$ref' was rewritten"
|
||||
git update-ref -m "filter-branch: rewrite" \
|
||||
"$ref" $rewritten $sha1 ||
|
||||
die "Could not rewrite $ref"
|
||||
if ! git update-ref -m "filter-branch: rewrite" \
|
||||
"$ref" $rewritten $sha1 2>/dev/null; then
|
||||
if test $(git cat-file -t "$ref") = tag; then
|
||||
if test -z "$filter_tag_name"; then
|
||||
warn "WARNING: You said to rewrite tagged commits, but not the corresponding tag."
|
||||
warn "WARNING: Perhaps use '--tag-name-filter cat' to rewrite the tag."
|
||||
fi
|
||||
else
|
||||
die "Could not rewrite $ref"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# NEEDSWORK: possibly add -Werror, making this an error
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=0.10.GITGUI
|
||||
DEF_VER=0.11.GITGUI
|
||||
|
||||
LF='
|
||||
'
|
||||
|
||||
@@ -145,7 +145,16 @@ pick_one () {
|
||||
}
|
||||
|
||||
pick_one_preserving_merges () {
|
||||
case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
|
||||
fast_forward=t
|
||||
case "$1" in
|
||||
-n)
|
||||
fast_forward=f
|
||||
sha1=$2
|
||||
;;
|
||||
*)
|
||||
sha1=$1
|
||||
;;
|
||||
esac
|
||||
sha1=$(git rev-parse $sha1)
|
||||
|
||||
if test -f "$DOTEST"/current-commit
|
||||
@@ -156,15 +165,14 @@ pick_one_preserving_merges () {
|
||||
die "Cannot write current commit's replacement sha1"
|
||||
fi
|
||||
|
||||
echo $sha1 > "$DOTEST"/current-commit
|
||||
|
||||
# rewrite parents; if none were rewritten, we can fast-forward.
|
||||
fast_forward=t
|
||||
preserve=t
|
||||
new_parents=
|
||||
for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
|
||||
do
|
||||
if test -f "$REWRITTEN"/$p
|
||||
then
|
||||
preserve=f
|
||||
new_p=$(cat "$REWRITTEN"/$p)
|
||||
test $p != $new_p && fast_forward=f
|
||||
case "$new_parents" in
|
||||
@@ -181,7 +189,8 @@ pick_one_preserving_merges () {
|
||||
case $fast_forward in
|
||||
t)
|
||||
output warn "Fast forward to $sha1"
|
||||
test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1
|
||||
output git reset --hard $sha1 ||
|
||||
die "Cannot fast forward to $sha1"
|
||||
;;
|
||||
f)
|
||||
test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
|
||||
@@ -191,7 +200,6 @@ pick_one_preserving_merges () {
|
||||
output git checkout $first_parent 2> /dev/null ||
|
||||
die "Cannot move HEAD to $first_parent"
|
||||
|
||||
echo $sha1 > "$DOTEST"/current-commit
|
||||
case "$new_parents" in
|
||||
' '*' '*)
|
||||
# redo merge
|
||||
|
||||
@@ -144,8 +144,19 @@ is_interactive () {
|
||||
done && test -n "$1"
|
||||
}
|
||||
|
||||
test -f "$GIT_DIR"/rebase-apply/applying &&
|
||||
die 'It looks like git-am is in progress. Cannot rebase.'
|
||||
|
||||
is_interactive "$@" && exec git-rebase--interactive "$@"
|
||||
|
||||
if test $# -eq 0
|
||||
then
|
||||
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || usage
|
||||
test -d "$dotest" -o -f "$GIT_DIR"/rebase-apply/rebasing &&
|
||||
die 'A rebase is in progress, try --continue, --skip or --abort.'
|
||||
die "No arguments given and $GIT_DIR/rebase-apply already exists."
|
||||
fi
|
||||
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
@@ -268,16 +279,16 @@ done
|
||||
# Make sure we do not have $GIT_DIR/rebase-apply
|
||||
if test -z "$do_merge"
|
||||
then
|
||||
if mkdir "$GIT_DIR"/rebase-apply
|
||||
if mkdir "$GIT_DIR"/rebase-apply 2>/dev/null
|
||||
then
|
||||
rmdir "$GIT_DIR"/rebase-apply
|
||||
else
|
||||
echo >&2 '
|
||||
It seems that I cannot create a '"$GIT_DIR"'/rebase-apply directory,
|
||||
and I wonder if you are in the middle of patch application or another
|
||||
It seems that I cannot create a rebase-apply directory, and
|
||||
I wonder if you are in the middle of patch application or another
|
||||
rebase. If that is not the case, please
|
||||
rm -fr '"$GIT_DIR"'/rebase-apply
|
||||
and run me again. I am stopping in case you still have something
|
||||
and run me again. I am stopping in case you still have something
|
||||
valuable there.'
|
||||
exit 1
|
||||
fi
|
||||
@@ -285,7 +296,7 @@ else
|
||||
if test -d "$dotest"
|
||||
then
|
||||
die "previous rebase directory $dotest still exists." \
|
||||
'try git-rebase < --continue | --abort >'
|
||||
'Try git rebase (--continue | --abort | --skip)'
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2007, Nanako Shiraishi
|
||||
|
||||
USAGE='[ | save | list | show | apply | clear | drop | pop | create | branch ]'
|
||||
dashless=$(basename "$0" | sed -e 's/-/ /')
|
||||
USAGE="list [<options>]
|
||||
or: $dashless (show | drop | pop ) [<stash>]
|
||||
or: $dashless apply [--index] [<stash>]
|
||||
or: $dashless branch <branchname> [<stash>]
|
||||
or: $dashless [save [--keep-index] [<message>]]
|
||||
or: $dashless clear"
|
||||
|
||||
SUBDIRECTORY_OK=Yes
|
||||
OPTIONS_SPEC=
|
||||
|
||||
142
git-svn.perl
142
git-svn.perl
@@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit,
|
||||
$_version, $_fetch_all, $_no_rebase,
|
||||
$_merge, $_strategy, $_dry_run, $_local,
|
||||
$_prefix, $_no_checkout, $_url, $_verbose,
|
||||
$_git_format);
|
||||
$_git_format, $_commit_url);
|
||||
$Git::SVN::_follow_parent = 1;
|
||||
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
|
||||
'config-dir=s' => \$Git::SVN::Ra::config_dir,
|
||||
@@ -127,6 +127,8 @@ my %cmd = (
|
||||
'verbose|v' => \$_verbose,
|
||||
'dry-run|n' => \$_dry_run,
|
||||
'fetch-all|all' => \$_fetch_all,
|
||||
'commit-url=s' => \$_commit_url,
|
||||
'revision|r=i' => \$_revision,
|
||||
'no-rebase' => \$_no_rebase,
|
||||
%cmt_opts, %fc_opts } ],
|
||||
'set-tree' => [ \&cmd_set_tree,
|
||||
@@ -169,7 +171,8 @@ my %cmd = (
|
||||
'color' => \$Git::SVN::Log::color,
|
||||
'pager=s' => \$Git::SVN::Log::pager
|
||||
} ],
|
||||
'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish",
|
||||
'find-rev' => [ \&cmd_find_rev,
|
||||
"Translate between SVN revision numbers and tree-ish",
|
||||
{} ],
|
||||
'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory",
|
||||
{ 'merge|m|M' => \$_merge,
|
||||
@@ -229,7 +232,9 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) {
|
||||
my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
|
||||
|
||||
read_repo_config(\%opts);
|
||||
Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame'));
|
||||
if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')) {
|
||||
Getopt::Long::Configure('pass_through');
|
||||
}
|
||||
my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
|
||||
'minimize-connections' => \$Git::SVN::Migration::_minimize,
|
||||
'id|i=s' => \$Git::SVN::default_ref_id,
|
||||
@@ -416,6 +421,8 @@ sub cmd_dcommit {
|
||||
$head ||= 'HEAD';
|
||||
my @refs;
|
||||
my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
|
||||
$url = $_commit_url if defined $_commit_url;
|
||||
my $last_rev = $_revision if defined $_revision;
|
||||
if ($url) {
|
||||
print "Committing to $url ...\n";
|
||||
}
|
||||
@@ -423,7 +430,6 @@ sub cmd_dcommit {
|
||||
die "Unable to determine upstream SVN information from ",
|
||||
"$head history.\nPerhaps the repository is empty.";
|
||||
}
|
||||
my $last_rev;
|
||||
my ($linear_refs, $parents) = linearize_history($gs, \@refs);
|
||||
if ($_no_rebase && scalar(@$linear_refs) > 1) {
|
||||
warn "Attempting to commit more than one change while ",
|
||||
@@ -446,7 +452,7 @@ sub cmd_dcommit {
|
||||
my $cmt_rev;
|
||||
my %ed_opts = ( r => $last_rev,
|
||||
log => get_commit_entry($d)->{log},
|
||||
ra => Git::SVN::Ra->new($gs->full_url),
|
||||
ra => Git::SVN::Ra->new($url),
|
||||
config => SVN::Core::config_get_config(
|
||||
$Git::SVN::Ra::config_dir
|
||||
),
|
||||
@@ -984,8 +990,10 @@ sub complete_url_ls_init {
|
||||
if (length $pfx && $pfx !~ m#/$#) {
|
||||
die "--prefix='$pfx' must have a trailing slash '/'\n";
|
||||
}
|
||||
command_noisy('config', "svn-remote.$gs->{repo_id}.$n",
|
||||
"$remote_path:refs/remotes/$pfx*");
|
||||
command_noisy('config',
|
||||
"svn-remote.$gs->{repo_id}.$n",
|
||||
"$remote_path:refs/remotes/$pfx*" .
|
||||
('/*' x (($remote_path =~ tr/*/*/) - 1)) );
|
||||
}
|
||||
|
||||
sub verify_ref {
|
||||
@@ -1257,7 +1265,7 @@ sub md5sum {
|
||||
my $arg = shift;
|
||||
my $ref = ref $arg;
|
||||
my $md5 = Digest::MD5->new();
|
||||
if ($ref eq 'GLOB' || $ref eq 'IO::File') {
|
||||
if ($ref eq 'GLOB' || $ref eq 'IO::File' || $ref eq 'File::Temp') {
|
||||
$md5->addfile($arg) or croak $!;
|
||||
} elsif ($ref eq 'SCALAR') {
|
||||
$md5->add($$arg) or croak $!;
|
||||
@@ -1320,6 +1328,7 @@ BEGIN {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my (%LOCKFILES, %INDEX_FILES);
|
||||
END {
|
||||
unlink keys %LOCKFILES if %LOCKFILES;
|
||||
@@ -3222,13 +3231,11 @@ sub change_file_prop {
|
||||
|
||||
sub apply_textdelta {
|
||||
my ($self, $fb, $exp) = @_;
|
||||
my $fh = IO::File->new_tmpfile;
|
||||
$fh->autoflush(1);
|
||||
my $fh = Git::temp_acquire('svn_delta');
|
||||
# $fh gets auto-closed() by SVN::TxDelta::apply(),
|
||||
# (but $base does not,) so dup() it for reading in close_file
|
||||
open my $dup, '<&', $fh or croak $!;
|
||||
my $base = IO::File->new_tmpfile;
|
||||
$base->autoflush(1);
|
||||
my $base = Git::temp_acquire('git_blob');
|
||||
if ($fb->{blob}) {
|
||||
print $base 'link ' if ($fb->{mode_a} == 120000);
|
||||
my $size = $::_repository->cat_blob($fb->{blob}, $base);
|
||||
@@ -3243,9 +3250,9 @@ sub apply_textdelta {
|
||||
}
|
||||
}
|
||||
seek $base, 0, 0 or croak $!;
|
||||
$fb->{fh} = $dup;
|
||||
$fb->{fh} = $fh;
|
||||
$fb->{base} = $base;
|
||||
[ SVN::TxDelta::apply($base, $fh, undef, $fb->{path}, $fb->{pool}) ];
|
||||
[ SVN::TxDelta::apply($base, $dup, undef, $fb->{path}, $fb->{pool}) ];
|
||||
}
|
||||
|
||||
sub close_file {
|
||||
@@ -3261,35 +3268,36 @@ sub close_file {
|
||||
"expected: $exp\n got: $got\n";
|
||||
}
|
||||
}
|
||||
sysseek($fh, 0, 0) or croak $!;
|
||||
if ($fb->{mode_b} == 120000) {
|
||||
eval {
|
||||
sysread($fh, my $buf, 5) == 5 or croak $!;
|
||||
$buf eq 'link ' or die "$path has mode 120000",
|
||||
" but is not a link";
|
||||
};
|
||||
if ($@) {
|
||||
warn "$@\n";
|
||||
sysseek($fh, 0, 0) or croak $!;
|
||||
sysseek($fh, 0, 0) or croak $!;
|
||||
sysread($fh, my $buf, 5) == 5 or croak $!;
|
||||
|
||||
unless ($buf eq 'link ') {
|
||||
warn "$path has mode 120000",
|
||||
" but is not a link\n";
|
||||
} else {
|
||||
my $tmp_fh = Git::temp_acquire('svn_hash');
|
||||
my $res;
|
||||
while ($res = sysread($fh, my $str, 1024)) {
|
||||
my $out = syswrite($tmp_fh, $str, $res);
|
||||
defined($out) && $out == $res
|
||||
or croak("write ",
|
||||
$tmp_fh->filename,
|
||||
": $!\n");
|
||||
}
|
||||
defined $res or croak $!;
|
||||
|
||||
($fh, $tmp_fh) = ($tmp_fh, $fh);
|
||||
Git::temp_release($tmp_fh, 1);
|
||||
}
|
||||
}
|
||||
|
||||
my ($tmp_fh, $tmp_filename) = File::Temp::tempfile(UNLINK => 1);
|
||||
my $result;
|
||||
while ($result = sysread($fh, my $string, 1024)) {
|
||||
my $wrote = syswrite($tmp_fh, $string, $result);
|
||||
defined($wrote) && $wrote == $result
|
||||
or croak("write $tmp_filename: $!\n");
|
||||
}
|
||||
defined $result or croak $!;
|
||||
close $tmp_fh or croak $!;
|
||||
|
||||
close $fh or croak $!;
|
||||
|
||||
$hash = $::_repository->hash_and_insert_object($tmp_filename);
|
||||
unlink($tmp_filename);
|
||||
$hash = $::_repository->hash_and_insert_object(
|
||||
$fh->filename);
|
||||
$hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n";
|
||||
close $fb->{base} or croak $!;
|
||||
|
||||
Git::temp_release($fb->{base}, 1);
|
||||
Git::temp_release($fh, 1);
|
||||
} else {
|
||||
$hash = $fb->{blob} or die "no blob information\n";
|
||||
}
|
||||
@@ -3659,7 +3667,7 @@ sub chg_file {
|
||||
} elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) {
|
||||
$self->change_file_prop($fbat,'svn:executable',undef);
|
||||
}
|
||||
my $fh = IO::File->new_tmpfile or croak $!;
|
||||
my $fh = Git::temp_acquire('git_blob');
|
||||
if ($m->{mode_b} =~ /^120/) {
|
||||
print $fh 'link ' or croak $!;
|
||||
$self->change_file_prop($fbat,'svn:special','*');
|
||||
@@ -3678,9 +3686,8 @@ sub chg_file {
|
||||
my $atd = $self->apply_textdelta($fbat, undef, $pool);
|
||||
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
|
||||
die "Checksum mismatch\nexpected: $exp\ngot: $got\n" if ($got ne $exp);
|
||||
Git::temp_release($fh, 1);
|
||||
$pool->clear;
|
||||
|
||||
close $fh or croak $!;
|
||||
}
|
||||
|
||||
sub D {
|
||||
@@ -4121,16 +4128,38 @@ sub gs_fetch_loop_common {
|
||||
Git::SVN::gc();
|
||||
}
|
||||
|
||||
sub get_dir_globbed {
|
||||
my ($self, $left, $depth, $r) = @_;
|
||||
|
||||
my @x = eval { $self->get_dir($left, $r) };
|
||||
return unless scalar @x == 3;
|
||||
my $dirents = $x[0];
|
||||
my @finalents;
|
||||
foreach my $de (keys %$dirents) {
|
||||
next if $dirents->{$de}->{kind} != $SVN::Node::dir;
|
||||
if ($depth > 1) {
|
||||
my @args = ("$left/$de", $depth - 1, $r);
|
||||
foreach my $dir ($self->get_dir_globbed(@args)) {
|
||||
push @finalents, "$de/$dir";
|
||||
}
|
||||
} else {
|
||||
push @finalents, $de;
|
||||
}
|
||||
}
|
||||
@finalents;
|
||||
}
|
||||
|
||||
sub match_globs {
|
||||
my ($self, $exists, $paths, $globs, $r) = @_;
|
||||
|
||||
sub get_dir_check {
|
||||
my ($self, $exists, $g, $r) = @_;
|
||||
my @x = eval { $self->get_dir($g->{path}->{left}, $r) };
|
||||
return unless scalar @x == 3;
|
||||
my $dirents = $x[0];
|
||||
foreach my $de (keys %$dirents) {
|
||||
next if $dirents->{$de}->{kind} != $SVN::Node::dir;
|
||||
|
||||
my @dirs = $self->get_dir_globbed($g->{path}->{left},
|
||||
$g->{path}->{depth},
|
||||
$r);
|
||||
|
||||
foreach my $de (@dirs) {
|
||||
my $p = $g->{path}->full_path($de);
|
||||
next if $exists->{$p};
|
||||
next if (length $g->{path}->{right} &&
|
||||
@@ -4912,15 +4941,20 @@ sub new {
|
||||
my ($class, $glob) = @_;
|
||||
my $re = $glob;
|
||||
$re =~ s!/+$!!g; # no need for trailing slashes
|
||||
my $nr = ($re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g);
|
||||
my ($left, $right) = ($1, $2);
|
||||
if ($nr > 1) {
|
||||
die "Only one '*' wildcard expansion ",
|
||||
"is supported (got $nr): '$glob'\n";
|
||||
} elsif ($nr == 0) {
|
||||
$re =~ m!^([^*]*)(\*(?:/\*)*)([^*]*)$!;
|
||||
my $temp = $re;
|
||||
my ($left, $right) = ($1, $3);
|
||||
$re = $2;
|
||||
my $depth = $re =~ tr/*/*/;
|
||||
if ($depth != $temp =~ tr/*/*/) {
|
||||
die "Only one set of wildcard directories " .
|
||||
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
|
||||
}
|
||||
if ($depth == 0) {
|
||||
die "One '*' is needed for glob: '$glob'\n";
|
||||
}
|
||||
$re = quotemeta($left) . $re . quotemeta($right);
|
||||
$re =~ s!\*!\[^/\]*!g;
|
||||
$re = quotemeta($left) . "($re)" . quotemeta($right);
|
||||
if (length $left && !($left =~ s!/+$!!g)) {
|
||||
die "Missing trailing '/' on left side of: '$glob' ($left)\n";
|
||||
}
|
||||
@@ -4929,7 +4963,7 @@ sub new {
|
||||
}
|
||||
my $left_re = qr/^\/\Q$left\E(\/|$)/;
|
||||
bless { left => $left, right => $right, left_regex => $left_re,
|
||||
regex => qr/$re/, glob => $glob }, $class;
|
||||
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
|
||||
}
|
||||
|
||||
sub full_path {
|
||||
|
||||
@@ -22,11 +22,11 @@ proc gitdir {} {
|
||||
# run before X event handlers, so reading from a fast source can
|
||||
# make the GUI completely unresponsive.
|
||||
proc run args {
|
||||
global isonrunq runq
|
||||
global isonrunq runq currunq
|
||||
|
||||
set script $args
|
||||
if {[info exists isonrunq($script)]} return
|
||||
if {$runq eq {}} {
|
||||
if {$runq eq {} && ![info exists currunq]} {
|
||||
after idle dorunq
|
||||
}
|
||||
lappend runq [list {} $script]
|
||||
@@ -38,10 +38,10 @@ proc filerun {fd script} {
|
||||
}
|
||||
|
||||
proc filereadable {fd script} {
|
||||
global runq
|
||||
global runq currunq
|
||||
|
||||
fileevent $fd readable {}
|
||||
if {$runq eq {}} {
|
||||
if {$runq eq {} && ![info exists currunq]} {
|
||||
after idle dorunq
|
||||
}
|
||||
lappend runq [list $fd $script]
|
||||
@@ -60,17 +60,19 @@ proc nukefile {fd} {
|
||||
}
|
||||
|
||||
proc dorunq {} {
|
||||
global isonrunq runq
|
||||
global isonrunq runq currunq
|
||||
|
||||
set tstart [clock clicks -milliseconds]
|
||||
set t0 $tstart
|
||||
while {[llength $runq] > 0} {
|
||||
set fd [lindex $runq 0 0]
|
||||
set script [lindex $runq 0 1]
|
||||
set currunq [lindex $runq 0]
|
||||
set runq [lrange $runq 1 end]
|
||||
set repeat [eval $script]
|
||||
unset currunq
|
||||
set t1 [clock clicks -milliseconds]
|
||||
set t [expr {$t1 - $t0}]
|
||||
set runq [lrange $runq 1 end]
|
||||
if {$repeat ne {} && $repeat} {
|
||||
if {$fd eq {} || $repeat == 2} {
|
||||
# script returns 1 if it wants to be readded
|
||||
|
||||
2
path.c
2
path.c
@@ -365,7 +365,7 @@ int normalize_absolute_path(char *buf, const char *path)
|
||||
* path = Canonical absolute path
|
||||
* prefix_list = Colon-separated list of absolute paths
|
||||
*
|
||||
* Determines, for each path in parent_list, whether the "prefix" really
|
||||
* Determines, for each path in prefix_list, whether the "prefix" really
|
||||
* is an ancestor directory of path. Returns the length of the longest
|
||||
* ancestor directory, excluding any trailing slashes, or -1 if no prefix
|
||||
* is an ancestor. (Note that this means 0 is returned if prefix_list is
|
||||
|
||||
130
perl/Git.pm
130
perl/Git.pm
@@ -57,7 +57,8 @@ require Exporter;
|
||||
command_output_pipe command_input_pipe command_close_pipe
|
||||
command_bidi_pipe command_close_bidi_pipe
|
||||
version exec_path hash_object git_cmd_try
|
||||
remote_refs);
|
||||
remote_refs
|
||||
temp_acquire temp_release temp_reset);
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -99,7 +100,7 @@ use Carp qw(carp croak); # but croak is bad - throw instead
|
||||
use Error qw(:try);
|
||||
use Cwd qw(abs_path);
|
||||
use IPC::Open2 qw(open2);
|
||||
|
||||
use Fcntl qw(SEEK_SET SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
@@ -933,6 +934,131 @@ sub _close_cat_blob {
|
||||
delete @$self{@vars};
|
||||
}
|
||||
|
||||
|
||||
{ # %TEMP_* Lexical Context
|
||||
|
||||
my (%TEMP_LOCKS, %TEMP_FILES);
|
||||
|
||||
=item temp_acquire ( NAME )
|
||||
|
||||
Attempts to retreive the temporary file mapped to the string C<NAME>. If an
|
||||
associated temp file has not been created this session or was closed, it is
|
||||
created, cached, and set for autoflush and binmode.
|
||||
|
||||
Internally locks the file mapped to C<NAME>. This lock must be released with
|
||||
C<temp_release()> when the temp file is no longer needed. Subsequent attempts
|
||||
to retrieve temporary files mapped to the same C<NAME> while still locked will
|
||||
cause an error. This locking mechanism provides a weak guarantee and is not
|
||||
threadsafe. It does provide some error checking to help prevent temp file refs
|
||||
writing over one another.
|
||||
|
||||
In general, the L<File::Handle> returned should not be closed by consumers as
|
||||
it defeats the purpose of this caching mechanism. If you need to close the temp
|
||||
file handle, then you should use L<File::Temp> or another temp file faculty
|
||||
directly. If a handle is closed and then requested again, then a warning will
|
||||
issue.
|
||||
|
||||
=cut
|
||||
|
||||
sub temp_acquire {
|
||||
my ($self, $name) = _maybe_self(@_);
|
||||
|
||||
my $temp_fd = _temp_cache($name);
|
||||
|
||||
$TEMP_LOCKS{$temp_fd} = 1;
|
||||
$temp_fd;
|
||||
}
|
||||
|
||||
=item temp_release ( NAME )
|
||||
|
||||
=item temp_release ( FILEHANDLE )
|
||||
|
||||
Releases a lock acquired through C<temp_acquire()>. Can be called either with
|
||||
the C<NAME> mapping used when acquiring the temp file or with the C<FILEHANDLE>
|
||||
referencing a locked temp file.
|
||||
|
||||
Warns if an attempt is made to release a file that is not locked.
|
||||
|
||||
The temp file will be truncated before being released. This can help to reduce
|
||||
disk I/O where the system is smart enough to detect the truncation while data
|
||||
is in the output buffers. Beware that after the temp file is released and
|
||||
truncated, any operations on that file may fail miserably until it is
|
||||
re-acquired. All contents are lost between each release and acquire mapped to
|
||||
the same string.
|
||||
|
||||
=cut
|
||||
|
||||
sub temp_release {
|
||||
my ($self, $temp_fd, $trunc) = _maybe_self(@_);
|
||||
|
||||
if (ref($temp_fd) ne 'File::Temp') {
|
||||
$temp_fd = $TEMP_FILES{$temp_fd};
|
||||
}
|
||||
unless ($TEMP_LOCKS{$temp_fd}) {
|
||||
carp "Attempt to release temp file '",
|
||||
$temp_fd, "' that has not been locked";
|
||||
}
|
||||
temp_reset($temp_fd) if $trunc and $temp_fd->opened;
|
||||
|
||||
$TEMP_LOCKS{$temp_fd} = 0;
|
||||
undef;
|
||||
}
|
||||
|
||||
sub _temp_cache {
|
||||
my ($name) = @_;
|
||||
|
||||
_verify_require();
|
||||
|
||||
my $temp_fd = \$TEMP_FILES{$name};
|
||||
if (defined $$temp_fd and $$temp_fd->opened) {
|
||||
if ($TEMP_LOCKS{$$temp_fd}) {
|
||||
throw Error::Simple("Temp file with moniker '",
|
||||
$name, "' already in use");
|
||||
}
|
||||
} else {
|
||||
if (defined $$temp_fd) {
|
||||
# then we're here because of a closed handle.
|
||||
carp "Temp file '", $name,
|
||||
"' was closed. Opening replacement.";
|
||||
}
|
||||
$$temp_fd = File::Temp->new(
|
||||
TEMPLATE => 'Git_XXXXXX',
|
||||
DIR => File::Spec->tmpdir
|
||||
) or throw Error::Simple("couldn't open new temp file");
|
||||
$$temp_fd->autoflush;
|
||||
binmode $$temp_fd;
|
||||
}
|
||||
$$temp_fd;
|
||||
}
|
||||
|
||||
sub _verify_require {
|
||||
eval { require File::Temp; require File::Spec; };
|
||||
$@ and throw Error::Simple($@);
|
||||
}
|
||||
|
||||
=item temp_reset ( FILEHANDLE )
|
||||
|
||||
Truncates and resets the position of the C<FILEHANDLE>.
|
||||
|
||||
=cut
|
||||
|
||||
sub temp_reset {
|
||||
my ($self, $temp_fd) = _maybe_self(@_);
|
||||
|
||||
truncate $temp_fd, 0
|
||||
or throw Error::Simple("couldn't truncate file");
|
||||
sysseek($temp_fd, 0, SEEK_SET) and seek($temp_fd, 0, SEEK_SET)
|
||||
or throw Error::Simple("couldn't seek to beginning of file");
|
||||
sysseek($temp_fd, 0, SEEK_CUR) == 0 and tell($temp_fd) == 0
|
||||
or throw Error::Simple("expected file position to be reset");
|
||||
}
|
||||
|
||||
sub END {
|
||||
unlink values %TEMP_FILES if %TEMP_FILES;
|
||||
}
|
||||
|
||||
} # %TEMP_* Lexical Context
|
||||
|
||||
=back
|
||||
|
||||
=head1 ERROR HANDLING
|
||||
|
||||
@@ -36,7 +36,7 @@ test_expect_success 'setup' '
|
||||
|
||||
test_expect_success 'am' '
|
||||
|
||||
git am --binary -3 <patchfile &&
|
||||
git am -3 <patchfile &&
|
||||
git diff-files --name-status --exit-code
|
||||
|
||||
'
|
||||
|
||||
@@ -188,16 +188,30 @@ test_expect_success 'delete' '
|
||||
test_tick &&
|
||||
git commit -m tiger C &&
|
||||
|
||||
test 5 = $(git reflog | wc -l) &&
|
||||
HEAD_entry_count=$(git reflog | wc -l)
|
||||
master_entry_count=$(git reflog show master | wc -l)
|
||||
|
||||
test $HEAD_entry_count = 5 &&
|
||||
test $master_entry_count = 5 &&
|
||||
|
||||
|
||||
git reflog delete master@{1} &&
|
||||
git reflog show master > output &&
|
||||
test 4 = $(wc -l < output) &&
|
||||
test $(($master_entry_count - 1)) = $(wc -l < output) &&
|
||||
test $HEAD_entry_count = $(git reflog | wc -l) &&
|
||||
! grep ox < output &&
|
||||
|
||||
master_entry_count=$(wc -l < output)
|
||||
|
||||
git reflog delete HEAD@{1} &&
|
||||
test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) &&
|
||||
test $master_entry_count = $(git reflog show master | wc -l) &&
|
||||
|
||||
HEAD_entry_count=$(git reflog | wc -l)
|
||||
|
||||
git reflog delete master@{07.04.2005.15:15:00.-0700} &&
|
||||
git reflog show master > output &&
|
||||
test 3 = $(wc -l < output) &&
|
||||
test $(($master_entry_count - 1)) = $(wc -l < output) &&
|
||||
! grep dragon < output
|
||||
|
||||
'
|
||||
|
||||
@@ -202,6 +202,9 @@ test_expect_success 'retain authorship when squashing' '
|
||||
test_expect_success '-p handles "no changes" gracefully' '
|
||||
HEAD=$(git rev-parse HEAD) &&
|
||||
git rebase -i -p HEAD^ &&
|
||||
git update-index --refresh &&
|
||||
git diff-files --quiet &&
|
||||
git diff-index --quiet --cached HEAD -- &&
|
||||
test $HEAD = $(git rev-parse HEAD)
|
||||
'
|
||||
|
||||
@@ -235,6 +238,9 @@ test_expect_success 'preserve merges with -p' '
|
||||
git checkout -b to-be-rebased &&
|
||||
test_tick &&
|
||||
git rebase -i -p --onto branch1 master &&
|
||||
git update-index --refresh &&
|
||||
git diff-files --quiet &&
|
||||
git diff-index --quiet --cached HEAD -- &&
|
||||
test $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&
|
||||
test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&
|
||||
test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&
|
||||
@@ -244,6 +250,18 @@ test_expect_success 'preserve merges with -p' '
|
||||
test $(git show HEAD:unrelated-file) = 1
|
||||
'
|
||||
|
||||
test_expect_success 'edit ancestor with -p' '
|
||||
FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 &&
|
||||
echo 2 > unrelated-file &&
|
||||
test_tick &&
|
||||
git commit -m L2-modified --amend unrelated-file &&
|
||||
git rebase --continue &&
|
||||
git update-index --refresh &&
|
||||
git diff-files --quiet &&
|
||||
git diff-index --quiet --cached HEAD -- &&
|
||||
test $(git show HEAD:unrelated-file) = 2
|
||||
'
|
||||
|
||||
test_expect_success '--continue tries to commit' '
|
||||
test_tick &&
|
||||
test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
|
||||
|
||||
@@ -232,4 +232,12 @@ test_expect_success 'git add (add.ignore-errors = false)' '
|
||||
|
||||
fi # skip chmod 0 tests
|
||||
|
||||
test_expect_success 'git add '\''fo\[ou\]bar'\'' ignores foobar' '
|
||||
git reset --hard &&
|
||||
touch fo\[ou\]bar foobar &&
|
||||
git add '\''fo\[ou\]bar'\'' &&
|
||||
git ls-files fo\[ou\]bar | grep -F fo\[ou\]bar &&
|
||||
! ( git ls-files foobar | grep foobar )
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -13,7 +13,8 @@ test_expect_success setup '
|
||||
echo " HT and SP indent" >>F &&
|
||||
echo "With trailing SP " >>F &&
|
||||
echo "Carriage ReturnQ" | tr Q "\015" >>F &&
|
||||
echo "No problem" >>F
|
||||
echo "No problem" >>F &&
|
||||
echo >>F
|
||||
|
||||
'
|
||||
|
||||
@@ -160,4 +161,21 @@ test_expect_success 'with cr-at-eol (attribute)' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'trailing empty lines (1)' '
|
||||
|
||||
rm -f .gitattributes &&
|
||||
test_must_fail git diff --check >output &&
|
||||
grep "ends with blank lines." output &&
|
||||
grep "trailing whitespace" output
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'trailing empty lines (2)' '
|
||||
|
||||
echo "F -whitespace" >.gitattributes &&
|
||||
git diff --check >output &&
|
||||
! test -s output
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
|
||||
'git mailsplit -o. ../t5100/sample.mbox >last &&
|
||||
last=`cat last` &&
|
||||
echo total is $last &&
|
||||
test `cat last` = 10'
|
||||
test `cat last` = 11'
|
||||
|
||||
for mail in `echo 00*`
|
||||
do
|
||||
|
||||
5
t/t5100/info0011
Normal file
5
t/t5100/info0011
Normal file
@@ -0,0 +1,5 @@
|
||||
Author: A U Thor
|
||||
Email: a.u.thor@example.com
|
||||
Subject: Xyzzy
|
||||
Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST)
|
||||
|
||||
2
t/t5100/msg0011
Normal file
2
t/t5100/msg0011
Normal file
@@ -0,0 +1,2 @@
|
||||
Here comes a commit log message, and
|
||||
its second line is here.
|
||||
22
t/t5100/patch0011
Normal file
22
t/t5100/patch0011
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
builtin-mailinfo.c | 4 ++--
|
||||
|
||||
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
|
||||
index 3e5fe51..aabfe5c 100644
|
||||
--- a/builtin-mailinfo.c
|
||||
+++ b/builtin-mailinfo.c
|
||||
@@ -758,8 +758,8 @@ static void handle_body(void)
|
||||
/* process any boundary lines */
|
||||
if (*content_top && is_multipart_boundary(&line)) {
|
||||
/* flush any leftover */
|
||||
- if (line.len)
|
||||
- handle_filter(&line);
|
||||
+ if (prev.len)
|
||||
+ handle_filter(&prev);
|
||||
|
||||
if (!handle_boundary())
|
||||
goto handle_body_out;
|
||||
--
|
||||
1.6.0.rc2
|
||||
|
||||
|
||||
@@ -465,3 +465,38 @@ index 962aa34..2d1520f 100644
|
||||
--
|
||||
1.5.6.2.455.g1efb2
|
||||
|
||||
From nobody Fri Aug 8 22:24:03 2008
|
||||
Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST)
|
||||
From: A U Thor <a.u.thor@example.com>
|
||||
Subject: [PATCH 3/3 v2] Xyzzy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="=-=-="
|
||||
|
||||
--=-=-=
|
||||
Content-Type: text/plain; charset=iso-8859-15
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Here comes a commit log message, and
|
||||
its second line is here.
|
||||
---
|
||||
builtin-mailinfo.c | 4 ++--
|
||||
|
||||
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
|
||||
index 3e5fe51..aabfe5c 100644
|
||||
--- a/builtin-mailinfo.c
|
||||
+++ b/builtin-mailinfo.c
|
||||
@@ -758,8 +758,8 @@ static void handle_body(void)
|
||||
/* process any boundary lines */
|
||||
if (*content_top && is_multipart_boundary(&line)) {
|
||||
/* flush any leftover */
|
||||
- if (line.len)
|
||||
- handle_filter(&line);
|
||||
+ if (prev.len)
|
||||
+ handle_filter(&prev);
|
||||
=20
|
||||
if (!handle_boundary())
|
||||
goto handle_body_out;
|
||||
--=20
|
||||
1.6.0.rc2
|
||||
|
||||
--=-=-=--
|
||||
|
||||
@@ -21,7 +21,7 @@ test_expect_success 'prune stale packs' '
|
||||
orig_pack=$(echo .git/objects/pack/*.pack) &&
|
||||
: > .git/objects/tmp_1.pack &&
|
||||
: > .git/objects/tmp_2.pack &&
|
||||
test-chmtime -86501 .git/objects/tmp_1.pack &&
|
||||
test-chmtime =-86501 .git/objects/tmp_1.pack &&
|
||||
git prune --expire 1.day &&
|
||||
test -f $orig_pack &&
|
||||
test -f .git/objects/tmp_2.pack &&
|
||||
@@ -39,7 +39,7 @@ test_expect_success 'prune --expire' '
|
||||
git prune --expire=1.hour.ago &&
|
||||
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
|
||||
test -f $BLOB_FILE &&
|
||||
test-chmtime -86500 $BLOB_FILE &&
|
||||
test-chmtime =-86500 $BLOB_FILE &&
|
||||
git prune --expire 1.day &&
|
||||
test $before = $(git count-objects | sed "s/ .*//") &&
|
||||
! test -f $BLOB_FILE
|
||||
@@ -53,11 +53,11 @@ test_expect_success 'gc: implicit prune --expire' '
|
||||
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
|
||||
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
|
||||
test -f $BLOB_FILE &&
|
||||
test-chmtime -$((86400*14-30)) $BLOB_FILE &&
|
||||
test-chmtime =-$((86400*14-30)) $BLOB_FILE &&
|
||||
git gc &&
|
||||
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
|
||||
test -f $BLOB_FILE &&
|
||||
test-chmtime -$((86400*14+1)) $BLOB_FILE &&
|
||||
test-chmtime =-$((86400*14+1)) $BLOB_FILE &&
|
||||
git gc &&
|
||||
test $before = $(git count-objects | sed "s/ .*//") &&
|
||||
! test -f $BLOB_FILE
|
||||
|
||||
@@ -41,7 +41,7 @@ test_expect_success 'setup remote repository' '
|
||||
git clone --bare test_repo test_repo.git &&
|
||||
cd test_repo.git &&
|
||||
git --bare update-server-info &&
|
||||
chmod +x hooks/post-update &&
|
||||
mv hooks/post-update.sample hooks/post-update &&
|
||||
cd - &&
|
||||
mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
|
||||
'
|
||||
|
||||
@@ -95,4 +95,16 @@ test_expect_success 'clone --bare names the local repository <name>.git' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'clone --mirror does not repeat tags' '
|
||||
|
||||
(cd src &&
|
||||
git tag some-tag HEAD) &&
|
||||
git clone --mirror src mirror2 &&
|
||||
(cd mirror2 &&
|
||||
git show-ref 2> clone.err > clone.out) &&
|
||||
test_must_fail grep Duplicate mirror2/clone.err &&
|
||||
grep some-tag mirror2/clone.out
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -16,7 +16,8 @@ test_expect_success 'test refspec globbing' '
|
||||
echo "goodbye world" > trunk/src/b/readme &&
|
||||
svn import -m "initial" trunk "$svnrepo"/trunk &&
|
||||
svn co "$svnrepo" tmp &&
|
||||
cd tmp &&
|
||||
(
|
||||
cd tmp &&
|
||||
mkdir branches tags &&
|
||||
svn add branches tags &&
|
||||
svn cp trunk branches/start &&
|
||||
@@ -37,7 +38,7 @@ test_expect_success 'test refspec globbing' '
|
||||
echo "byebye" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "nothing to see here"
|
||||
cd .. &&
|
||||
) &&
|
||||
git config --add svn-remote.svn.url "$svnrepo" &&
|
||||
git config --add svn-remote.svn.fetch \
|
||||
"trunk/src/a:refs/remotes/trunk" &&
|
||||
@@ -48,11 +49,12 @@ test_expect_success 'test refspec globbing' '
|
||||
git-svn multi-fetch &&
|
||||
git log --pretty=oneline refs/remotes/tags/end | \
|
||||
sed -e "s/^.\{41\}//" > output.end &&
|
||||
cmp expect.end output.end &&
|
||||
test_cmp expect.end output.end &&
|
||||
test "`git rev-parse refs/remotes/tags/end~1`" = \
|
||||
"`git rev-parse refs/remotes/branches/start`" &&
|
||||
test "`git rev-parse refs/remotes/branches/start~2`" = \
|
||||
"`git rev-parse refs/remotes/trunk`"
|
||||
"`git rev-parse refs/remotes/trunk`" &&
|
||||
test_must_fail git rev-parse refs/remotes/tags/end@3
|
||||
'
|
||||
|
||||
echo try to try > expect.two
|
||||
@@ -66,11 +68,12 @@ test_expect_success 'test left-hand-side only globbing' '
|
||||
"branches/*:refs/remotes/two/branches/*" &&
|
||||
git config --add svn-remote.two.tags \
|
||||
"tags/*:refs/remotes/two/tags/*" &&
|
||||
cd tmp &&
|
||||
(
|
||||
cd tmp &&
|
||||
echo "try try" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "try to try"
|
||||
cd .. &&
|
||||
) &&
|
||||
git-svn fetch two &&
|
||||
test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
|
||||
test `git rev-list refs/remotes/two/branches/start | wc -l` -eq 3 &&
|
||||
@@ -80,7 +83,29 @@ test_expect_success 'test left-hand-side only globbing' '
|
||||
`git rev-parse refs/remotes/two/branches/start` &&
|
||||
git log --pretty=oneline refs/remotes/two/tags/end | \
|
||||
sed -e "s/^.\{41\}//" > output.two &&
|
||||
cmp expect.two output.two
|
||||
test_cmp expect.two output.two
|
||||
'
|
||||
|
||||
echo "Only one set of wildcard directories" \
|
||||
"(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
|
||||
echo "" >> expect.three
|
||||
|
||||
test_expect_success 'test disallow multi-globs' '
|
||||
git config --add svn-remote.three.url "$svnrepo" &&
|
||||
git config --add svn-remote.three.fetch \
|
||||
trunk:refs/remotes/three/trunk &&
|
||||
git config --add svn-remote.three.branches \
|
||||
"branches/*/t/*:refs/remotes/three/branches/*" &&
|
||||
git config --add svn-remote.three.tags \
|
||||
"tags/*/*:refs/remotes/three/tags/*" &&
|
||||
(
|
||||
cd tmp &&
|
||||
echo "try try" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "try to try"
|
||||
) &&
|
||||
test_must_fail git-svn fetch three 2> stderr.three &&
|
||||
test_cmp expect.three stderr.three
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
160
t/t9108-git-svn-multi-glob.sh
Executable file
160
t/t9108-git-svn-multi-glob.sh
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2007 Eric Wong
|
||||
test_description='git-svn globbing refspecs'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
cat > expect.end <<EOF
|
||||
the end
|
||||
hi
|
||||
start a new branch
|
||||
initial
|
||||
EOF
|
||||
|
||||
test_expect_success 'test refspec globbing' '
|
||||
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
|
||||
echo "hello world" > trunk/src/a/readme &&
|
||||
echo "goodbye world" > trunk/src/b/readme &&
|
||||
svn import -m "initial" trunk "$svnrepo"/trunk &&
|
||||
svn co "$svnrepo" tmp &&
|
||||
(
|
||||
cd tmp &&
|
||||
mkdir branches branches/v1 tags &&
|
||||
svn add branches tags &&
|
||||
svn cp trunk branches/v1/start &&
|
||||
svn commit -m "start a new branch" &&
|
||||
svn up &&
|
||||
echo "hi" >> branches/v1/start/src/b/readme &&
|
||||
poke branches/v1/start/src/b/readme &&
|
||||
echo "hey" >> branches/v1/start/src/a/readme &&
|
||||
poke branches/v1/start/src/a/readme &&
|
||||
svn commit -m "hi" &&
|
||||
svn up &&
|
||||
svn cp branches/v1/start tags/end &&
|
||||
echo "bye" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
echo "aye" >> tags/end/src/a/readme &&
|
||||
poke tags/end/src/a/readme &&
|
||||
svn commit -m "the end" &&
|
||||
echo "byebye" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "nothing to see here"
|
||||
) &&
|
||||
git config --add svn-remote.svn.url "$svnrepo" &&
|
||||
git config --add svn-remote.svn.fetch \
|
||||
"trunk/src/a:refs/remotes/trunk" &&
|
||||
git config --add svn-remote.svn.branches \
|
||||
"branches/*/*/src/a:refs/remotes/branches/*/*" &&
|
||||
git config --add svn-remote.svn.tags\
|
||||
"tags/*/src/a:refs/remotes/tags/*" &&
|
||||
git-svn multi-fetch &&
|
||||
git log --pretty=oneline refs/remotes/tags/end | \
|
||||
sed -e "s/^.\{41\}//" > output.end &&
|
||||
test_cmp expect.end output.end &&
|
||||
test "`git rev-parse refs/remotes/tags/end~1`" = \
|
||||
"`git rev-parse refs/remotes/branches/v1/start`" &&
|
||||
test "`git rev-parse refs/remotes/branches/v1/start~2`" = \
|
||||
"`git rev-parse refs/remotes/trunk`" &&
|
||||
test_must_fail git rev-parse refs/remotes/tags/end@3
|
||||
'
|
||||
|
||||
echo try to try > expect.two
|
||||
echo nothing to see here >> expect.two
|
||||
cat expect.end >> expect.two
|
||||
|
||||
test_expect_success 'test left-hand-side only globbing' '
|
||||
git config --add svn-remote.two.url "$svnrepo" &&
|
||||
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
|
||||
git config --add svn-remote.two.branches \
|
||||
"branches/*/*:refs/remotes/two/branches/*/*" &&
|
||||
git config --add svn-remote.two.tags \
|
||||
"tags/*:refs/remotes/two/tags/*" &&
|
||||
(
|
||||
cd tmp &&
|
||||
echo "try try" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "try to try"
|
||||
) &&
|
||||
git-svn fetch two &&
|
||||
test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
|
||||
test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 &&
|
||||
test `git rev-parse refs/remotes/two/branches/v1/start~2` = \
|
||||
`git rev-parse refs/remotes/two/trunk` &&
|
||||
test `git rev-parse refs/remotes/two/tags/end~3` = \
|
||||
`git rev-parse refs/remotes/two/branches/v1/start` &&
|
||||
git log --pretty=oneline refs/remotes/two/tags/end | \
|
||||
sed -e "s/^.\{41\}//" > output.two &&
|
||||
test_cmp expect.two output.two
|
||||
'
|
||||
cat > expect.four <<EOF
|
||||
adios
|
||||
adding more
|
||||
Changed 2 in v2/start
|
||||
Another versioned branch
|
||||
initial
|
||||
EOF
|
||||
|
||||
test_expect_success 'test another branch' '
|
||||
(
|
||||
cd tmp &&
|
||||
mkdir branches/v2 &&
|
||||
svn add branches/v2 &&
|
||||
svn cp trunk branches/v2/start &&
|
||||
svn commit -m "Another versioned branch" &&
|
||||
svn up &&
|
||||
echo "hello" >> branches/v2/start/src/b/readme &&
|
||||
poke branches/v2/start/src/b/readme &&
|
||||
echo "howdy" >> branches/v2/start/src/a/readme &&
|
||||
poke branches/v2/start/src/a/readme &&
|
||||
svn commit -m "Changed 2 in v2/start" &&
|
||||
svn up &&
|
||||
svn cp branches/v2/start tags/next &&
|
||||
echo "bye" >> tags/next/src/b/readme &&
|
||||
poke tags/next/src/b/readme &&
|
||||
echo "aye" >> tags/next/src/a/readme &&
|
||||
poke tags/next/src/a/readme &&
|
||||
svn commit -m "adding more" &&
|
||||
echo "byebye" >> tags/next/src/b/readme &&
|
||||
poke tags/next/src/b/readme &&
|
||||
svn commit -m "adios"
|
||||
) &&
|
||||
git config --add svn-remote.four.url "$svnrepo" &&
|
||||
git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk &&
|
||||
git config --add svn-remote.four.branches \
|
||||
"branches/*/*:refs/remotes/four/branches/*/*" &&
|
||||
git config --add svn-remote.four.tags \
|
||||
"tags/*:refs/remotes/four/tags/*" &&
|
||||
git-svn fetch four &&
|
||||
test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 &&
|
||||
test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 &&
|
||||
test `git rev-parse refs/remotes/four/branches/v2/start~2` = \
|
||||
`git rev-parse refs/remotes/four/trunk` &&
|
||||
test `git rev-parse refs/remotes/four/tags/next~2` = \
|
||||
`git rev-parse refs/remotes/four/branches/v2/start` &&
|
||||
git log --pretty=oneline refs/remotes/four/tags/next | \
|
||||
sed -e "s/^.\{41\}//" > output.four &&
|
||||
test_cmp expect.four output.four
|
||||
'
|
||||
|
||||
echo "Only one set of wildcard directories" \
|
||||
"(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
|
||||
echo "" >> expect.three
|
||||
|
||||
test_expect_success 'test disallow multiple globs' '
|
||||
git config --add svn-remote.three.url "$svnrepo" &&
|
||||
git config --add svn-remote.three.fetch \
|
||||
trunk:refs/remotes/three/trunk &&
|
||||
git config --add svn-remote.three.branches \
|
||||
"branches/*/t/*:refs/remotes/three/branches/*/*" &&
|
||||
git config --add svn-remote.three.tags \
|
||||
"tags/*:refs/remotes/three/tags/*" &&
|
||||
(
|
||||
cd tmp &&
|
||||
echo "try try" >> tags/end/src/b/readme &&
|
||||
poke tags/end/src/b/readme &&
|
||||
svn commit -m "try to try"
|
||||
) &&
|
||||
test_must_fail git-svn fetch three 2> stderr.three &&
|
||||
test_cmp expect.three stderr.three
|
||||
'
|
||||
|
||||
test_done
|
||||
37
t/t9125-git-svn-multi-glob-branch-names.sh
Executable file
37
t/t9125-git-svn-multi-glob-branch-names.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2008 Marcus Griep
|
||||
|
||||
test_description='git-svn multi-glob branch names'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'setup svnrepo' '
|
||||
mkdir project project/trunk project/branches \
|
||||
project/branches/v14.1 project/tags &&
|
||||
echo foo > project/trunk/foo &&
|
||||
svn import -m "$test_description" project "$svnrepo/project" &&
|
||||
rm -rf project &&
|
||||
svn cp -m "fun" "$svnrepo/project/trunk" \
|
||||
"$svnrepo/project/branches/v14.1/beta" &&
|
||||
svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \
|
||||
"$svnrepo/project/branches/v14.1/gold"
|
||||
'
|
||||
|
||||
test_expect_success 'test clone with multi-glob in branch names' '
|
||||
git svn clone -T trunk -b branches/*/* -t tags \
|
||||
"$svnrepo/project" project &&
|
||||
cd project &&
|
||||
git rev-parse "refs/remotes/v14.1/beta" &&
|
||||
git rev-parse "refs/remotes/v14.1/gold" &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
test_expect_success 'test dcommit to multi-globbed branch' "
|
||||
cd project &&
|
||||
git reset --hard 'refs/remotes/v14.1/gold' &&
|
||||
echo hello >> foo &&
|
||||
git commit -m 'hello' -- foo &&
|
||||
git svn dcommit &&
|
||||
cd ..
|
||||
"
|
||||
|
||||
test_done
|
||||
@@ -1045,7 +1045,7 @@ DATA
|
||||
INPUT_END
|
||||
|
||||
test_expect_success 'P: fail on inline gitlink' '
|
||||
! git-fast-import <input'
|
||||
test_must_fail git-fast-import <input'
|
||||
|
||||
test_tick
|
||||
cat >input <<INPUT_END
|
||||
@@ -1068,6 +1068,6 @@ M 160000 :1 sub
|
||||
INPUT_END
|
||||
|
||||
test_expect_success 'P: fail on blob mark in gitlink' '
|
||||
! git-fast-import <input'
|
||||
test_must_fail git-fast-import <input'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -15,7 +15,7 @@ int length_callback(const struct option *opt, const char *arg, int unset)
|
||||
if (unset)
|
||||
return 1; /* do not support unset */
|
||||
|
||||
*(unsigned long *)opt->value = strlen(arg);
|
||||
*(int *)opt->value = strlen(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
13
transport.c
13
transport.c
@@ -463,17 +463,14 @@ static struct ref *get_refs_via_curl(struct transport *transport)
|
||||
run_active_slot(slot);
|
||||
if (results.curl_result != CURLE_OK) {
|
||||
strbuf_release(&buffer);
|
||||
if (missing_target(&results)) {
|
||||
return NULL;
|
||||
} else {
|
||||
error("%s", curl_errorstr);
|
||||
return NULL;
|
||||
}
|
||||
if (missing_target(&results))
|
||||
die("%s not found: did you run git update-server-info on the server?", refs_url);
|
||||
else
|
||||
die("%s download error - %s", refs_url, curl_errorstr);
|
||||
}
|
||||
} else {
|
||||
strbuf_release(&buffer);
|
||||
error("Unable to start request");
|
||||
return NULL;
|
||||
die("Unable to start HTTP request");
|
||||
}
|
||||
|
||||
data = buffer.buf;
|
||||
|
||||
Reference in New Issue
Block a user