Compare commits
123 Commits
Author | SHA1 | Date | |
---|---|---|---|
3bd1bb327e | |||
1966af8176 | |||
bc69776aa1 | |||
c6d8f7635f | |||
213152688c | |||
db12d97542 | |||
bff82d0cda | |||
197cf8d59c | |||
0122cf6611 | |||
f7af75777f | |||
c3067cbfb3 | |||
bb11eb31a2 | |||
1c9f54417e | |||
1f398ee772 | |||
5b841d61c4 | |||
de551d472e | |||
61e6108d94 | |||
747f9d30ed | |||
714fddf2fc | |||
aa41cf8f43 | |||
20ff3ec28e | |||
39470cf961 | |||
ce8936c342 | |||
835a3eea3e | |||
be18f4b899 | |||
acb0b7b01f | |||
38b7ccbe8c | |||
4f6a32f8af | |||
e1dc49bcde | |||
3346330d70 | |||
5ab2f7b2ce | |||
cb365a7a56 | |||
1e7ef0253c | |||
8afd317843 | |||
b5a18787bd | |||
66c9e7d487 | |||
7634817871 | |||
f054a41941 | |||
5bd27ebb18 | |||
1b89eaa4be | |||
fd94836923 | |||
bf637803a7 | |||
8c7f788238 | |||
b19293df9e | |||
dcbf041745 | |||
ba7906f2f4 | |||
67f1fe5f08 | |||
abfd5fa872 | |||
7b60d0d3e4 | |||
510a309e5e | |||
8e4f767ba7 | |||
b8fee3a388 | |||
63801da88d | |||
17e61b8288 | |||
3be1f18e1b | |||
9d5156496d | |||
81db4abf84 | |||
fb8b193670 | |||
5a688fe470 | |||
2d266f9d62 | |||
a8fac795dd | |||
19fa5e8c4d | |||
5d83f9c198 | |||
389d176771 | |||
b0de555410 | |||
2a5643da73 | |||
e8bd78c3fc | |||
720fe22d50 | |||
cd747dc6dc | |||
3460a60064 | |||
d83a42f34a | |||
1d52b02696 | |||
a42dea3281 | |||
cbc8c61041 | |||
0abd52772b | |||
150115aded | |||
4e218f54b3 | |||
3e5970a41e | |||
93467ee660 | |||
67c176f549 | |||
7ad3c52e2d | |||
c0250b6477 | |||
923cc82c48 | |||
8af95ca017 | |||
2aa93deec0 | |||
10a73f5848 | |||
3c954c23d6 | |||
0e1aa2f7af | |||
e10d48de74 | |||
2990034f1e | |||
b60df87a6b | |||
094085e336 | |||
c90d565a46 | |||
869a3d34c1 | |||
76aac71546 | |||
4d6acb7041 | |||
79bc4c7155 | |||
171110a4a6 | |||
92cd872202 | |||
4306bcb4e1 | |||
821d56aa68 | |||
ee9cf14d25 | |||
aa9ea77de4 | |||
e5ac1217eb | |||
b89510f024 | |||
236425919b | |||
3f7cdf3299 | |||
9326d49412 | |||
aab3b9a1aa | |||
aaab4b9fb9 | |||
7efaeba2a8 | |||
fa685bdf45 | |||
db75ada559 | |||
ac8463d2b4 | |||
3e0c4ffdbd | |||
56384e61ea | |||
ce163c793d | |||
69e020ae00 | |||
03a9683d22 | |||
386cb77210 | |||
b8431b033f | |||
cd673c1f17 | |||
2478dc84b5 |
45
Documentation/RelNotes-1.6.2.2.txt
Normal file
45
Documentation/RelNotes-1.6.2.2.txt
Normal file
@ -0,0 +1,45 @@
|
||||
GIT v1.6.2.2 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.2.1
|
||||
--------------------
|
||||
|
||||
* A longstanding confusing description of what --pickaxe option of
|
||||
git-diff does has been clarified in the documentation.
|
||||
|
||||
* "git-blame -S" did not quite work near the commits that were given
|
||||
on the command line correctly.
|
||||
|
||||
* "git diff --pickaxe-regexp" did not count overlapping matches
|
||||
correctly.
|
||||
|
||||
* "git diff" did not feed files in work-tree representation to external
|
||||
diff and textconv.
|
||||
|
||||
* "git-fetch" in a repository that was not cloned from anywhere said
|
||||
it cannot find 'origin', which was hard to understand for new people.
|
||||
|
||||
* "git-format-patch --numbered-files --stdout" did not have to die of
|
||||
incompatible options; it now simply ignores --numbered-files as no files
|
||||
are produced anyway.
|
||||
|
||||
* "git-ls-files --deleted" did not work well with GIT_DIR&GIT_WORK_TREE.
|
||||
|
||||
* "git-read-tree A B C..." without -m option has been broken for a long
|
||||
time.
|
||||
|
||||
* git-send-email ignored --in-reply-to when --no-thread was given.
|
||||
|
||||
* 'git-submodule add' did not tolerate extra slashes and ./ in the path it
|
||||
accepted from the command line; it now is more lenient.
|
||||
|
||||
* git-svn misbehaved when the project contained a path that began with
|
||||
two dashes.
|
||||
|
||||
* import-zips script (in contrib) did not compute the common directory
|
||||
prefix correctly.
|
||||
|
||||
* miscompilation of negated enum constants by old gcc (2.9) affected the
|
||||
codepaths to spawn subprocesses.
|
||||
|
||||
Many small documentation updates are included as well.
|
22
Documentation/RelNotes-1.6.2.3.txt
Normal file
22
Documentation/RelNotes-1.6.2.3.txt
Normal file
@ -0,0 +1,22 @@
|
||||
GIT v1.6.2.3 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.2.2
|
||||
--------------------
|
||||
|
||||
* Setting an octal mode value to core.sharedrepository configuration to
|
||||
restrict access to the repository to group members did not work as
|
||||
advertised.
|
||||
|
||||
* A fairly large and trivial memory leak while rev-list shows list of
|
||||
reachable objects has been identified and plugged.
|
||||
|
||||
* "git-commit --interactive" did not abort when underlying "git-add -i"
|
||||
signaled a failure.
|
||||
|
||||
* git-repack (invoked from git-gc) did not work as nicely as it should in
|
||||
a repository that borrows objects from neighbours via alternates
|
||||
mechanism especially when some packs are marked with the ".keep" flag
|
||||
to prevent them from being repacked.
|
||||
|
||||
Many small documentation updates are included as well.
|
@ -39,7 +39,7 @@ of lines before or after the line given by <start>.
|
||||
Show raw timestamp (Default: off).
|
||||
|
||||
-S <revs-file>::
|
||||
Use revs from revs-file instead of calling linkgit:git-rev-list[1].
|
||||
Use revisions from revs-file instead of calling linkgit:git-rev-list[1].
|
||||
|
||||
--reverse::
|
||||
Walk history forward instead of backward. Instead of showing
|
||||
|
@ -176,7 +176,10 @@ override configuration settings.
|
||||
number.
|
||||
|
||||
-S<string>::
|
||||
Look for differences that contain the change in <string>.
|
||||
Look for differences that introduce or remove an instance of
|
||||
<string>. Note that this is different than the string simply
|
||||
appearing in diff output; see the 'pickaxe' entry in
|
||||
linkgit:gitdiffcore[7] for more details.
|
||||
|
||||
--pickaxe-all::
|
||||
When -S finds a change, show all the changes in that
|
||||
|
@ -98,7 +98,7 @@ Use a tarball as a starting point for a new repository.::
|
||||
------------
|
||||
$ tar zxf frotz.tar.gz
|
||||
$ cd frotz
|
||||
$ git-init
|
||||
$ git init
|
||||
$ git add . <1>
|
||||
$ git commit -m "import of frotz source tree."
|
||||
$ git tag v2.43 <2>
|
||||
|
@ -22,7 +22,7 @@ prepended to the filenames in the archive.
|
||||
|
||||
'git-archive' behaves differently when given a tree ID versus when
|
||||
given a commit ID or tag ID. In the first case the current time is
|
||||
used as modification time of each file in the archive. In the latter
|
||||
used as the modification time of each file in the archive. In the latter
|
||||
case the commit time as recorded in the referenced commit object is
|
||||
used instead. Additionally the commit ID is stored in a global
|
||||
extended pax header if the tar format is used; it can be extracted
|
||||
@ -48,11 +48,11 @@ OPTIONS
|
||||
Prepend <prefix>/ to each filename in the archive.
|
||||
|
||||
<extra>::
|
||||
This can be any options that the archiver backend understand.
|
||||
This can be any options that the archiver backend understands.
|
||||
See next section.
|
||||
|
||||
--remote=<repo>::
|
||||
Instead of making a tar archive from local repository,
|
||||
Instead of making a tar archive from the local repository,
|
||||
retrieve a tar archive from a remote repository.
|
||||
|
||||
--exec=<git-upload-archive>::
|
||||
@ -105,7 +105,7 @@ EXAMPLES
|
||||
git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)::
|
||||
|
||||
Create a tar archive that contains the contents of the
|
||||
latest commit on the current branch, and extracts it in
|
||||
latest commit on the current branch, and extract it in the
|
||||
`/var/tmp/junk` directory.
|
||||
|
||||
git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
|
||||
|
@ -3,7 +3,7 @@ git-bisect(1)
|
||||
|
||||
NAME
|
||||
----
|
||||
git-bisect - Find the change that introduced a bug by binary search
|
||||
git-bisect - Find by binary search the change that introduced a bug
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
@ -39,7 +39,8 @@ help" or "git bisect -h" to get a long usage description.
|
||||
Basic bisect commands: start, bad, good
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The way you use it is:
|
||||
Using the Linux kernel tree as an example, basic use of the bisect
|
||||
command is as follows:
|
||||
|
||||
------------------------------------------------
|
||||
$ git bisect start
|
||||
@ -48,61 +49,63 @@ $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 was the last version
|
||||
# tested that was good
|
||||
------------------------------------------------
|
||||
|
||||
When you give at least one bad and one good versions, it will bisect
|
||||
the revision tree and say something like:
|
||||
When you have specified at least one bad and one good version, the
|
||||
command bisects the revision tree and outputs something similar to
|
||||
the following:
|
||||
|
||||
------------------------------------------------
|
||||
Bisecting: 675 revisions left to test after this
|
||||
------------------------------------------------
|
||||
|
||||
and check out the state in the middle. Now, compile that kernel, and
|
||||
boot it. Now, let's say that this booted kernel works fine, then just
|
||||
do
|
||||
The state in the middle of the set of revisions is then checked out.
|
||||
You would now compile that kernel and boot it. If the booted kernel
|
||||
works correctly, you would then issue the following command:
|
||||
|
||||
------------------------------------------------
|
||||
$ git bisect good # this one is good
|
||||
------------------------------------------------
|
||||
|
||||
which will now say
|
||||
The output of this command would be something similar to the following:
|
||||
|
||||
------------------------------------------------
|
||||
Bisecting: 337 revisions left to test after this
|
||||
------------------------------------------------
|
||||
|
||||
and you continue along, compiling that one, testing it, and depending
|
||||
on whether it is good or bad, you say "git bisect good" or "git bisect
|
||||
bad", and ask for the next bisection.
|
||||
You keep repeating this process, compiling the tree, testing it, and
|
||||
depending on whether it is good or bad issuing the command "git bisect good"
|
||||
or "git bisect bad" to ask for the next bisection.
|
||||
|
||||
Until you have no more left, and you'll have been left with the first
|
||||
bad kernel rev in "refs/bisect/bad".
|
||||
Eventually there will be no more revisions left to bisect, and you
|
||||
will have been left with the first bad kernel revision in "refs/bisect/bad".
|
||||
|
||||
Bisect reset
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Oh, and then after you want to reset to the original head, do a
|
||||
To return to the original head after a bisect session, issue the
|
||||
following command:
|
||||
|
||||
------------------------------------------------
|
||||
$ git bisect reset
|
||||
------------------------------------------------
|
||||
|
||||
to get back to the original branch, instead of being on the bisection
|
||||
commit ("git bisect start" will do that for you too, actually: it will
|
||||
reset the bisection state).
|
||||
This resets the tree to the original branch instead of being on the
|
||||
bisection commit ("git bisect start" will also do that, as it resets
|
||||
the bisection state).
|
||||
|
||||
Bisect visualize
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
During the bisection process, you can say
|
||||
To see the currently remaining suspects in 'gitk', issue the following
|
||||
command during the bisection process:
|
||||
|
||||
------------
|
||||
$ git bisect visualize
|
||||
------------
|
||||
|
||||
to see the currently remaining suspects in 'gitk'. `visualize` is a bit
|
||||
too long to type and `view` is provided as a synonym.
|
||||
`view` may also be used as a synonym for `visualize`.
|
||||
|
||||
If 'DISPLAY' environment variable is not set, 'git log' is used
|
||||
instead. You can even give command line options such as `-p` and
|
||||
If the 'DISPLAY' environment variable is not set, 'git log' is used
|
||||
instead. You can also give command line options such as `-p` and
|
||||
`--stat`.
|
||||
|
||||
------------
|
||||
@ -112,57 +115,58 @@ $ git bisect view --stat
|
||||
Bisect log and bisect replay
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The good/bad input is logged, and
|
||||
After having marked revisions as good or bad, issue the following
|
||||
command to show what has been done so far:
|
||||
|
||||
------------
|
||||
$ git bisect log
|
||||
------------
|
||||
|
||||
shows what you have done so far. You can truncate its output somewhere
|
||||
and save it in a file, and run
|
||||
If you discover that you made a mistake in specifying the status of a
|
||||
revision, you can save the output of this command to a file, edit it to
|
||||
remove the incorrect entries, and then issue the following commands to
|
||||
return to a corrected state:
|
||||
|
||||
------------
|
||||
$ git bisect reset
|
||||
$ git bisect replay that-file
|
||||
------------
|
||||
|
||||
if you find later you made a mistake telling good/bad about a
|
||||
revision.
|
||||
|
||||
Avoiding to test a commit
|
||||
Avoiding testing a commit
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If in a middle of bisect session, you know what the bisect suggested
|
||||
to try next is not a good one to test (e.g. the change the commit
|
||||
If, in the middle of a bisect session, you know that the next suggested
|
||||
revision is not a good one to test (e.g. the change the commit
|
||||
introduces is known not to work in your environment and you know it
|
||||
does not have anything to do with the bug you are chasing), you may
|
||||
want to find a near-by commit and try that instead.
|
||||
want to find a nearby commit and try that instead.
|
||||
|
||||
It goes something like this:
|
||||
For example:
|
||||
|
||||
------------
|
||||
$ git bisect good/bad # previous round was good/bad.
|
||||
$ git bisect good/bad # previous round was good or bad.
|
||||
Bisecting: 337 revisions left to test after this
|
||||
$ git bisect visualize # oops, that is uninteresting.
|
||||
$ git reset --hard HEAD~3 # try 3 revs before what
|
||||
$ git reset --hard HEAD~3 # try 3 revisions before what
|
||||
# was suggested
|
||||
------------
|
||||
|
||||
Then compile and test the one you chose to try. After that, tell
|
||||
bisect what the result was as usual.
|
||||
Then compile and test the chosen revision, and afterwards mark
|
||||
the revision as good or bad in the usual manner.
|
||||
|
||||
Bisect skip
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Instead of choosing by yourself a nearby commit, you may just want git
|
||||
to do it for you using:
|
||||
Instead of choosing by yourself a nearby commit, you can ask git
|
||||
to do it for you by issuing the command:
|
||||
|
||||
------------
|
||||
$ git bisect skip # Current version cannot be tested
|
||||
------------
|
||||
|
||||
But computing the commit to test may be slower afterwards and git may
|
||||
eventually not be able to tell the first bad among a bad and one or
|
||||
more "skip"ped commits.
|
||||
eventually not be able to tell the first bad commit among a bad commit
|
||||
and one or more skipped commits.
|
||||
|
||||
You can even skip a range of commits, instead of just one commit,
|
||||
using the "'<commit1>'..'<commit2>'" notation. For example:
|
||||
@ -171,33 +175,34 @@ using the "'<commit1>'..'<commit2>'" notation. For example:
|
||||
$ git bisect skip v2.5..v2.6
|
||||
------------
|
||||
|
||||
would mean that no commit between `v2.5` excluded and `v2.6` included
|
||||
can be tested.
|
||||
This tells the bisect process that no commit after `v2.5`, up to and
|
||||
including `v2.6`, should be tested.
|
||||
|
||||
Note that if you want to also skip the first commit of a range you can
|
||||
use something like:
|
||||
Note that if you also want to skip the first commit of the range you
|
||||
would issue the command:
|
||||
|
||||
------------
|
||||
$ git bisect skip v2.5 v2.5..v2.6
|
||||
------------
|
||||
|
||||
and the commit pointed to by `v2.5` will be skipped too.
|
||||
This tells the bisect process that the commits between `v2.5` included
|
||||
and `v2.6` included should be skipped.
|
||||
|
||||
|
||||
Cutting down bisection by giving more parameters to bisect start
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can further cut down the number of trials if you know what part of
|
||||
the tree is involved in the problem you are tracking down, by giving
|
||||
paths parameters when you say `bisect start`, like this:
|
||||
You can further cut down the number of trials, if you know what part of
|
||||
the tree is involved in the problem you are tracking down, by specifying
|
||||
path parameters when issuing the `bisect start` command:
|
||||
|
||||
------------
|
||||
$ git bisect start -- arch/i386 include/asm-i386
|
||||
------------
|
||||
|
||||
If you know beforehand more than one good commits, you can narrow the
|
||||
bisect space down without doing the whole tree checkout every time you
|
||||
give good commits. You give the bad revision immediately after `start`
|
||||
and then you give all the good revisions you have:
|
||||
If you know beforehand more than one good commit, you can narrow the
|
||||
bisect space down by specifying all of the good commits immediately after
|
||||
the bad commit when issuing the `bisect start` command:
|
||||
|
||||
------------
|
||||
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
|
||||
@ -209,38 +214,38 @@ Bisect run
|
||||
~~~~~~~~~~
|
||||
|
||||
If you have a script that can tell if the current source code is good
|
||||
or bad, you can automatically bisect using:
|
||||
or bad, you can bisect by issuing the command:
|
||||
|
||||
------------
|
||||
$ git bisect run my_script
|
||||
------------
|
||||
|
||||
Note that the "run" script (`my_script` in the above example) should
|
||||
exit with code 0 in case the current source code is good. Exit with a
|
||||
Note that the script (`my_script` in the above example) should
|
||||
exit with code 0 if the current source code is good, and exit with a
|
||||
code between 1 and 127 (inclusive), except 125, if the current
|
||||
source code is bad.
|
||||
|
||||
Any other exit code will abort the automatic bisect process. (A
|
||||
program that does "exit(-1)" leaves $? = 255, see exit(3) manual page,
|
||||
the value is chopped with "& 0377".)
|
||||
Any other exit code will abort the bisect process. It should be noted
|
||||
that a program that terminates via "exit(-1)" leaves $? = 255, (see the
|
||||
exit(3) manual page), as the value is chopped with "& 0377".
|
||||
|
||||
The special exit code 125 should be used when the current source code
|
||||
cannot be tested. If the "run" script exits with this code, the current
|
||||
revision will be skipped, see `git bisect skip` above.
|
||||
cannot be tested. If the script exits with this code, the current
|
||||
revision will be skipped (see `git bisect skip` above).
|
||||
|
||||
You may often find that during bisect you want to have near-constant
|
||||
tweaks (e.g., s/#define DEBUG 0/#define DEBUG 1/ in a header file, or
|
||||
"revision that does not have this commit needs this patch applied to
|
||||
work around other problem this bisection is not interested in")
|
||||
applied to the revision being tested.
|
||||
You may often find that during a bisect session you want to have
|
||||
temporary modifications (e.g. s/#define DEBUG 0/#define DEBUG 1/ in a
|
||||
header file, or "revision that does not have this commit needs this
|
||||
patch applied to work around another problem this bisection is not
|
||||
interested in") applied to the revision being tested.
|
||||
|
||||
To cope with such a situation, after the inner 'git bisect' finds the
|
||||
next revision to test, with the "run" script, you can apply that tweak
|
||||
before compiling, run the real test, and after the test decides if the
|
||||
revision (possibly with the needed tweaks) passed the test, rewind the
|
||||
tree to the pristine state. Finally the "run" script can exit with
|
||||
the status of the real test to let the "git bisect run" command loop to
|
||||
determine the outcome.
|
||||
next revision to test, the script can apply the patch
|
||||
before compiling, run the real test, and afterwards decide if the
|
||||
revision (possibly with the needed patch) passed the test and then
|
||||
rewind the tree to the pristine state. Finally the script should exit
|
||||
with the status of the real test to let the "git bisect run" command loop
|
||||
determine the eventual outcome of the bisect session.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
@ -257,39 +262,39 @@ $ git bisect run make # "make" builds the app
|
||||
------------
|
||||
$ cat ~/test.sh
|
||||
#!/bin/sh
|
||||
make || exit 125 # this "skip"s broken builds
|
||||
make || exit 125 # this skips broken builds
|
||||
make test # "make test" runs the test suite
|
||||
$ git bisect start v1.3 v1.1 -- # v1.3 is bad, v1.1 is good
|
||||
$ git bisect run ~/test.sh
|
||||
------------
|
||||
+
|
||||
Here we use a "test.sh" custom script. In this script, if "make"
|
||||
fails, we "skip" the current commit.
|
||||
fails, we skip the current commit.
|
||||
+
|
||||
It's safer to use a custom script outside the repo to prevent
|
||||
It is safer to use a custom script outside the repository to prevent
|
||||
interactions between the bisect, make and test processes and the
|
||||
script.
|
||||
+
|
||||
And "make test" should "exit 0", if the test suite passes, and
|
||||
"exit 1" (for example) otherwise.
|
||||
"make test" should "exit 0", if the test suite passes, and
|
||||
"exit 1" otherwise.
|
||||
|
||||
* Automatically bisect a broken test case:
|
||||
+
|
||||
------------
|
||||
$ cat ~/test.sh
|
||||
#!/bin/sh
|
||||
make || exit 125 # this "skip"s broken builds
|
||||
make || exit 125 # this skips broken builds
|
||||
~/check_test_case.sh # does the test case passes ?
|
||||
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
|
||||
$ git bisect run ~/test.sh
|
||||
------------
|
||||
+
|
||||
Here "check_test_case.sh" should "exit 0", if the test case passes,
|
||||
and "exit 1" (for example) otherwise.
|
||||
Here "check_test_case.sh" should "exit 0" if the test case passes,
|
||||
and "exit 1" otherwise.
|
||||
+
|
||||
It's safer if both "test.sh" and "check_test_case.sh" scripts are
|
||||
outside the repo to prevent interactions between the bisect, make and
|
||||
test processes and the scripts.
|
||||
It is safer if both "test.sh" and "check_test_case.sh" scripts are
|
||||
outside the repository to prevent interactions between the bisect,
|
||||
make and test processes and the scripts.
|
||||
|
||||
Author
|
||||
------
|
||||
|
@ -18,9 +18,9 @@ DESCRIPTION
|
||||
Annotates each line in the given file with information from the revision which
|
||||
last modified the line. Optionally, start annotating from the given revision.
|
||||
|
||||
Also it can limit the range of lines annotated.
|
||||
The command can also limit the range of lines annotated.
|
||||
|
||||
This report doesn't tell you anything about lines which have been deleted or
|
||||
The report does not tell you anything about lines which have been deleted or
|
||||
replaced; you need to use a tool such as 'git-diff' or the "pickaxe"
|
||||
interface briefly mentioned in the following paragraph.
|
||||
|
||||
@ -48,26 +48,26 @@ include::blame-options.txt[]
|
||||
lines between files (see `-C`) and lines moved within a
|
||||
file (see `-M`). The first number listed is the score.
|
||||
This is the number of alphanumeric characters detected
|
||||
to be moved between or within files. This must be above
|
||||
as having been moved between or within files. This must be above
|
||||
a certain threshold for 'git-blame' to consider those lines
|
||||
of code to have been moved.
|
||||
|
||||
-f::
|
||||
--show-name::
|
||||
Show filename in the original commit. By default
|
||||
filename is shown if there is any line that came from a
|
||||
file with different name, due to rename detection.
|
||||
Show the filename in the original commit. By default
|
||||
the filename is shown if there is any line that came from a
|
||||
file with a different name, due to rename detection.
|
||||
|
||||
-n::
|
||||
--show-number::
|
||||
Show line number in the original commit (Default: off).
|
||||
Show the line number in the original commit (Default: off).
|
||||
|
||||
-s::
|
||||
Suppress author name and timestamp from the output.
|
||||
Suppress the author name and timestamp from the output.
|
||||
|
||||
-w::
|
||||
Ignore whitespace when comparing parent's version and
|
||||
child's to find where the lines came from.
|
||||
Ignore whitespace when comparing the parent's version and
|
||||
the child's to find where the lines came from.
|
||||
|
||||
|
||||
THE PORCELAIN FORMAT
|
||||
@ -79,17 +79,17 @@ header at the minimum has the first line which has:
|
||||
- 40-byte SHA-1 of the commit the line is attributed to;
|
||||
- the line number of the line in the original file;
|
||||
- the line number of the line in the final file;
|
||||
- on a line that starts a group of line from a different
|
||||
- on a line that starts a group of lines from a different
|
||||
commit than the previous one, the number of lines in this
|
||||
group. On subsequent lines this field is absent.
|
||||
|
||||
This header line is followed by the following information
|
||||
at least once for each commit:
|
||||
|
||||
- author name ("author"), email ("author-mail"), time
|
||||
- the author name ("author"), email ("author-mail"), time
|
||||
("author-time"), and timezone ("author-tz"); similarly
|
||||
for committer.
|
||||
- filename in the commit the line is attributed to.
|
||||
- the filename in the commit that the line is attributed to.
|
||||
- the first line of the commit log message ("summary").
|
||||
|
||||
The contents of the actual line is output after the above
|
||||
@ -100,23 +100,23 @@ header elements later.
|
||||
SPECIFYING RANGES
|
||||
-----------------
|
||||
|
||||
Unlike 'git-blame' and 'git-annotate' in older git, the extent
|
||||
of annotation can be limited to both line ranges and revision
|
||||
Unlike 'git-blame' and 'git-annotate' in older versions of git, the extent
|
||||
of the annotation can be limited to both line ranges and revision
|
||||
ranges. When you are interested in finding the origin for
|
||||
ll. 40-60 for file `foo`, you can use `-L` option like these
|
||||
lines 40-60 for file `foo`, you can use the `-L` option like so
|
||||
(they mean the same thing -- both ask for 21 lines starting at
|
||||
line 40):
|
||||
|
||||
git blame -L 40,60 foo
|
||||
git blame -L 40,+21 foo
|
||||
|
||||
Also you can use regular expression to specify the line range.
|
||||
Also you can use a regular expression to specify the line range:
|
||||
|
||||
git blame -L '/^sub hello {/,/^}$/' foo
|
||||
|
||||
would limit the annotation to the body of `hello` subroutine.
|
||||
which limits the annotation to the body of the `hello` subroutine.
|
||||
|
||||
When you are not interested in changes older than the version
|
||||
When you are not interested in changes older than version
|
||||
v2.6.18, or changes older than 3 weeks, you can use revision
|
||||
range specifiers similar to 'git-rev-list':
|
||||
|
||||
@ -129,7 +129,7 @@ commit v2.6.18 or the most recent commit that is more than 3
|
||||
weeks old in the above example) are blamed for that range
|
||||
boundary commit.
|
||||
|
||||
A particularly useful way is to see if an added file have lines
|
||||
A particularly useful way is to see if an added file has lines
|
||||
created by copy-and-paste from existing files. Sometimes this
|
||||
indicates that the developer was being sloppy and did not
|
||||
refactor the code properly. You can first find the commit that
|
||||
@ -162,26 +162,26 @@ annotated.
|
||||
+
|
||||
Line numbers count from 1.
|
||||
|
||||
. The first time that commit shows up in the stream, it has various
|
||||
. The first time that a commit shows up in the stream, it has various
|
||||
other information about it printed out with a one-word tag at the
|
||||
beginning of each line about that "extended commit info" (author,
|
||||
email, committer, dates, summary etc).
|
||||
beginning of each line describing the extra commit information (author,
|
||||
email, committer, dates, summary, etc.).
|
||||
|
||||
. Unlike Porcelain format, the filename information is always
|
||||
. Unlike the Porcelain format, the filename information is always
|
||||
given and terminates the entry:
|
||||
|
||||
"filename" <whitespace-quoted-filename-goes-here>
|
||||
+
|
||||
and thus it's really quite easy to parse for some line- and word-oriented
|
||||
and thus it is really quite easy to parse for some line- and word-oriented
|
||||
parser (which should be quite natural for most scripting languages).
|
||||
+
|
||||
[NOTE]
|
||||
For people who do parsing: to make it more robust, just ignore any
|
||||
lines in between the first and last one ("<sha1>" and "filename" lines)
|
||||
where you don't recognize the tag-words (or care about that particular
|
||||
lines between the first and last one ("<sha1>" and "filename" lines)
|
||||
where you do not recognize the tag words (or care about that particular
|
||||
one) at the beginning of the "extended information" lines. That way, if
|
||||
there is ever added information (like the commit encoding or extended
|
||||
commit commentary), a blame viewer won't ever care.
|
||||
commit commentary), a blame viewer will not care.
|
||||
|
||||
|
||||
MAPPING AUTHORS
|
||||
|
@ -18,19 +18,19 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
With no arguments, existing branches are listed, the current branch will
|
||||
With no arguments, existing branches are listed and the current branch will
|
||||
be highlighted with an asterisk. Option `-r` causes the remote-tracking
|
||||
branches to be listed, and option `-a` shows both.
|
||||
|
||||
With `--contains`, shows only the branches that contains the named commit
|
||||
(in other words, the branches whose tip commits are descendant of the
|
||||
With `--contains`, shows only the branches that contain the named commit
|
||||
(in other words, the branches whose tip commits are descendants of the
|
||||
named commit). With `--merged`, only branches merged into the named
|
||||
commit (i.e. the branches whose tip commits are reachable from the named
|
||||
commit) will be listed. With `--no-merged` only branches not merged into
|
||||
the named commit will be listed. Missing <commit> argument defaults to
|
||||
'HEAD' (i.e. the tip of the current branch).
|
||||
the named commit will be listed. If the <commit> argument is missing it
|
||||
defaults to 'HEAD' (i.e. the tip of the current branch).
|
||||
|
||||
In its second form, a new branch named <branchname> will be created.
|
||||
In the command's second form, a new branch named <branchname> will be created.
|
||||
It will start out with a head equal to the one given as <start-point>.
|
||||
If no <start-point> is given, the branch will be created with a head
|
||||
equal to that of the currently checked out branch.
|
||||
@ -57,9 +57,9 @@ has a reflog then the reflog will also be deleted.
|
||||
|
||||
Use -r together with -d to delete remote-tracking branches. Note, that it
|
||||
only makes sense to delete remote-tracking branches if they no longer exist
|
||||
in remote repository or if 'git-fetch' was configured not to fetch
|
||||
them again. See also 'prune' subcommand of linkgit:git-remote[1] for way to
|
||||
clean up all obsolete remote-tracking branches.
|
||||
in the remote repository or if 'git-fetch' was configured not to fetch
|
||||
them again. See also the 'prune' subcommand of linkgit:git-remote[1] for a
|
||||
way to clean up all obsolete remote-tracking branches.
|
||||
|
||||
|
||||
OPTIONS
|
||||
@ -83,7 +83,7 @@ OPTIONS
|
||||
Move/rename a branch and the corresponding reflog.
|
||||
|
||||
-M::
|
||||
Move/rename a branch even if the new branchname already exists.
|
||||
Move/rename a branch even if the new branch name already exists.
|
||||
|
||||
--color::
|
||||
Color branches to highlight current, local, and remote branches.
|
||||
@ -103,17 +103,17 @@ OPTIONS
|
||||
Show sha1 and commit subject line for each head.
|
||||
|
||||
--abbrev=<length>::
|
||||
Alter minimum display length for sha1 in output listing,
|
||||
default value is 7.
|
||||
Alter the sha1's minimum display length in the output listing.
|
||||
The default value is 7.
|
||||
|
||||
--no-abbrev::
|
||||
Display the full sha1s in output listing rather than abbreviating them.
|
||||
Display the full sha1s in the output listing rather than abbreviating them.
|
||||
|
||||
--track::
|
||||
When creating a new branch, set up configuration so that 'git-pull'
|
||||
When creating a new branch, set up the configuration so that 'git-pull'
|
||||
will automatically retrieve data from the start point, which must be
|
||||
a branch. Use this if you always pull from the same upstream branch
|
||||
into the new branch, and if you don't want to use "git pull
|
||||
into the new branch, and if you do not want to use "git pull
|
||||
<repository> <refspec>" explicitly. This behavior is the default
|
||||
when the start point is a remote branch. Set the
|
||||
branch.autosetupmerge configuration variable to `false` if you want
|
||||
@ -149,13 +149,13 @@ OPTIONS
|
||||
|
||||
<newbranch>::
|
||||
The new name for an existing branch. The same restrictions as for
|
||||
<branchname> applies.
|
||||
<branchname> apply.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Start development off of a known tag::
|
||||
Start development from a known tag::
|
||||
+
|
||||
------------
|
||||
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
|
||||
@ -167,7 +167,7 @@ $ git checkout my2.6.14
|
||||
<1> This step and the next one could be combined into a single step with
|
||||
"checkout -b my2.6.14 v2.6.14".
|
||||
|
||||
Delete unneeded branch::
|
||||
Delete an unneeded branch::
|
||||
+
|
||||
------------
|
||||
$ git clone git://git.kernel.org/.../git.git my.git
|
||||
@ -176,21 +176,21 @@ $ git branch -d -r origin/todo origin/html origin/man <1>
|
||||
$ git branch -D test <2>
|
||||
------------
|
||||
+
|
||||
<1> Delete remote-tracking branches "todo", "html", "man". Next 'fetch' or
|
||||
'pull' will create them again unless you configure them not to. See
|
||||
linkgit:git-fetch[1].
|
||||
<2> Delete "test" branch even if the "master" branch (or whichever branch is
|
||||
currently checked out) does not have all commits from test branch.
|
||||
<1> Delete the remote-tracking branches "todo", "html" and "man". The next
|
||||
'fetch' or 'pull' will create them again unless you configure them not to.
|
||||
See linkgit:git-fetch[1].
|
||||
<2> Delete the "test" branch even if the "master" branch (or whichever branch
|
||||
is currently checked out) does not have all commits from the test branch.
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
If you are creating a branch that you want to immediately checkout, it's
|
||||
If you are creating a branch that you want to checkout immediately, it is
|
||||
easier to use the git checkout command with its `-b` option to create
|
||||
a branch and check it out with a single command.
|
||||
|
||||
The options `--contains`, `--merged` and `--no-merged` serves three related
|
||||
The options `--contains`, `--merged` and `--no-merged` serve three related
|
||||
but different purposes:
|
||||
|
||||
- `--contains <commit>` is used to find all branches which will need
|
||||
|
@ -19,13 +19,13 @@ DESCRIPTION
|
||||
|
||||
Some workflows require that one or more branches of development on one
|
||||
machine be replicated on another machine, but the two machines cannot
|
||||
be directly connected so the interactive git protocols (git, ssh,
|
||||
rsync, http) cannot be used. This command provides support for
|
||||
be directly connected, and therefore the interactive git protocols (git,
|
||||
ssh, rsync, http) cannot be used. This command provides support for
|
||||
'git-fetch' and 'git-pull' to operate by packaging objects and references
|
||||
in an archive at the originating machine, then importing those into
|
||||
another repository using 'git-fetch' and 'git-pull'
|
||||
after moving the archive by some means (i.e., by sneakernet). As no
|
||||
direct connection between repositories exists, the user must specify a
|
||||
direct connection between the repositories exists, the user must specify a
|
||||
basis for the bundle that is held by the destination repository: the
|
||||
bundle assumes that all objects in the basis are already in the
|
||||
destination repository.
|
||||
@ -43,7 +43,7 @@ verify <file>::
|
||||
bundle format itself as well as checking that the prerequisite
|
||||
commits exist and are fully linked in the current repository.
|
||||
'git-bundle' prints a list of missing commits, if any, and exits
|
||||
with non-zero status.
|
||||
with a non-zero status.
|
||||
|
||||
list-heads <file>::
|
||||
Lists the references defined in the bundle. If followed by a
|
||||
@ -53,14 +53,14 @@ list-heads <file>::
|
||||
unbundle <file>::
|
||||
Passes the objects in the bundle to 'git-index-pack'
|
||||
for storage in the repository, then prints the names of all
|
||||
defined references. If a reflist is given, only references
|
||||
matching those in the given list are printed. This command is
|
||||
defined references. If a list of references is given, only
|
||||
references matching those in the list are printed. This command is
|
||||
really plumbing, intended to be called only by 'git-fetch'.
|
||||
|
||||
[git-rev-list-args...]::
|
||||
A list of arguments, acceptable to 'git-rev-parse' and
|
||||
'git-rev-list', that specify the specific objects and references
|
||||
to transport. For example, "master~10..master" causes the
|
||||
'git-rev-list', that specifies the specific objects and references
|
||||
to transport. For example, `master\~10..master` causes the
|
||||
current master reference to be packaged along with all objects
|
||||
added since its 10th ancestor commit. There is no explicit
|
||||
limit to the number of references and objects that may be
|
||||
@ -71,24 +71,24 @@ unbundle <file>::
|
||||
A list of references used to limit the references reported as
|
||||
available. This is principally of use to 'git-fetch', which
|
||||
expects to receive only those references asked for and not
|
||||
necessarily everything in the pack (in this case, 'git-bundle' is
|
||||
acting like 'git-fetch-pack').
|
||||
necessarily everything in the pack (in this case, 'git-bundle' acts
|
||||
like 'git-fetch-pack').
|
||||
|
||||
SPECIFYING REFERENCES
|
||||
---------------------
|
||||
|
||||
'git-bundle' will only package references that are shown by
|
||||
'git-show-ref': this includes heads, tags, and remote heads. References
|
||||
such as master~1 cannot be packaged, but are perfectly suitable for
|
||||
such as `master\~1` cannot be packaged, but are perfectly suitable for
|
||||
defining the basis. More than one reference may be packaged, and more
|
||||
than one basis can be specified. The objects packaged are those not
|
||||
contained in the union of the given bases. Each basis can be
|
||||
specified explicitly (e.g., ^master~10), or implicitly (e.g.,
|
||||
master~10..master, --since=10.days.ago master).
|
||||
specified explicitly (e.g. `^master\~10`), or implicitly (e.g.
|
||||
`master\~10..master`, `--since=10.days.ago master`).
|
||||
|
||||
It is very important that the basis used be held by the destination.
|
||||
It is okay to err on the side of conservatism, causing the bundle file
|
||||
to contain objects already in the destination as these are ignored
|
||||
It is okay to err on the side of caution, causing the bundle file
|
||||
to contain objects already in the destination, as these are ignored
|
||||
when unpacking at the destination.
|
||||
|
||||
EXAMPLE
|
||||
@ -97,13 +97,13 @@ EXAMPLE
|
||||
Assume you want to transfer the history from a repository R1 on machine A
|
||||
to another repository R2 on machine B.
|
||||
For whatever reason, direct connection between A and B is not allowed,
|
||||
but we can move data from A to B via some mechanism (CD, email, etc).
|
||||
We want to update R2 with developments made on branch master in R1.
|
||||
but we can move data from A to B via some mechanism (CD, email, etc.).
|
||||
We want to update R2 with development made on the branch master in R1.
|
||||
|
||||
To bootstrap the process, you can first create a bundle that doesn't have
|
||||
any basis. You can use a tag to remember up to what commit you sent out
|
||||
in order to make it easy to later update the other repository with
|
||||
incremental bundle,
|
||||
To bootstrap the process, you can first create a bundle that does not have
|
||||
any basis. You can use a tag to remember up to what commit you last
|
||||
processed, in order to make it easy to later update the other repository
|
||||
with an incremental bundle:
|
||||
|
||||
----------------
|
||||
machineA$ cd R1
|
||||
@ -111,17 +111,17 @@ machineA$ git bundle create file.bundle master
|
||||
machineA$ git tag -f lastR2bundle master
|
||||
----------------
|
||||
|
||||
Then you sneakernet file.bundle to the target machine B. Because you don't
|
||||
have to have any object to extract objects from such a bundle, not only
|
||||
you can fetch/pull from a bundle, you can clone from it as if it was a
|
||||
remote repository.
|
||||
Then you transfer file.bundle to the target machine B. If you are creating
|
||||
the repository on machine B, then you can clone from the bundle as if it
|
||||
were a remote repository instead of creating an empty repository and then
|
||||
pulling or fetching objects from the bundle:
|
||||
|
||||
----------------
|
||||
machineB$ git clone /home/me/tmp/file.bundle R2
|
||||
----------------
|
||||
|
||||
This will define a remote called "origin" in the resulting repository that
|
||||
lets you fetch and pull from the bundle. $GIT_DIR/config file in R2 may
|
||||
lets you fetch and pull from the bundle. The $GIT_DIR/config file in R2 will
|
||||
have an entry like this:
|
||||
|
||||
------------------------
|
||||
@ -130,12 +130,12 @@ have an entry like this:
|
||||
fetch = refs/heads/*:refs/remotes/origin/*
|
||||
------------------------
|
||||
|
||||
You can fetch/pull to update the resulting mine.git repository after
|
||||
replacing the bundle you store at /home/me/tmp/file.bundle with incremental
|
||||
updates from here on.
|
||||
To update the resulting mine.git repository, you can fetch or pull after
|
||||
replacing the bundle stored at /home/me/tmp/file.bundle with incremental
|
||||
updates.
|
||||
|
||||
After working more in the original repository, you can create an
|
||||
incremental bundle to update the other:
|
||||
After working some more in the original repository, you can create an
|
||||
incremental bundle to update the other repository:
|
||||
|
||||
----------------
|
||||
machineA$ cd R1
|
||||
@ -143,8 +143,8 @@ machineA$ git bundle create file.bundle lastR2bundle..master
|
||||
machineA$ git tag -f lastR2bundle master
|
||||
----------------
|
||||
|
||||
and sneakernet it to the other machine to replace /home/me/tmp/file.bundle,
|
||||
and pull from it.
|
||||
You then transfer the bundle to the other machine to replace
|
||||
/home/me/tmp/file.bundle, and pull from it.
|
||||
|
||||
----------------
|
||||
machineB$ cd R2
|
||||
@ -152,49 +152,49 @@ machineB$ git pull
|
||||
----------------
|
||||
|
||||
If you know up to what commit the intended recipient repository should
|
||||
have the necessary objects for, you can use that knowledge to specify the
|
||||
have the necessary objects, you can use that knowledge to specify the
|
||||
basis, giving a cut-off point to limit the revisions and objects that go
|
||||
in the resulting bundle. The previous example used lastR2bundle tag
|
||||
for this purpose, but you can use other options you would give to
|
||||
for this purpose, but you can use any other options that you would give to
|
||||
the linkgit:git-log[1] command. Here are more examples:
|
||||
|
||||
You can use a tag that is present in both.
|
||||
You can use a tag that is present in both:
|
||||
|
||||
----------------
|
||||
$ git bundle create mybundle v1.0.0..master
|
||||
----------------
|
||||
|
||||
You can use a basis based on time.
|
||||
You can use a basis based on time:
|
||||
|
||||
----------------
|
||||
$ git bundle create mybundle --since=10.days master
|
||||
----------------
|
||||
|
||||
Or you can use the number of commits.
|
||||
You can use the number of commits:
|
||||
|
||||
----------------
|
||||
$ git bundle create mybundle -10 master
|
||||
----------------
|
||||
|
||||
You can run `git-bundle verify` to see if you can extract from a bundle
|
||||
that was created with a basis.
|
||||
that was created with a basis:
|
||||
|
||||
----------------
|
||||
$ git bundle verify mybundle
|
||||
----------------
|
||||
|
||||
This will list what commits you must have in order to extract from the
|
||||
bundle and will error out if you don't have them.
|
||||
bundle and will error out if you do not have them.
|
||||
|
||||
A bundle from a recipient repository's point of view is just like a
|
||||
regular repository it fetches/pulls from. You can for example map
|
||||
refs, like this example, when fetching:
|
||||
regular repository which it fetches or pulls from. You can, for example, map
|
||||
references when fetching:
|
||||
|
||||
----------------
|
||||
$ git fetch mybundle master:localRef
|
||||
----------------
|
||||
|
||||
Or see what refs it offers.
|
||||
You can also see what references it offers.
|
||||
|
||||
----------------
|
||||
$ git ls-remote mybundle
|
||||
|
@ -3,7 +3,7 @@ git-cat-file(1)
|
||||
|
||||
NAME
|
||||
----
|
||||
git-cat-file - Provide content or type/size information for repository objects
|
||||
git-cat-file - Provide content or type and size information for repository objects
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
@ -14,19 +14,19 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
In the first form, provides content or type of objects in the repository. The
|
||||
type is required unless '-t' or '-p' is used to find the object type, or '-s'
|
||||
is used to find the object size.
|
||||
In its first form, the command provides the content or the type of an object in
|
||||
the repository. The type is required unless '-t' or '-p' is used to find the
|
||||
object type, or '-s' is used to find the object size.
|
||||
|
||||
In the second form, a list of object (separated by LFs) is provided on stdin,
|
||||
and the SHA1, type, and size of each object is printed on stdout.
|
||||
In the second form, a list of objects (separated by linefeeds) is provided on
|
||||
stdin, and the SHA1, type, and size of each object is printed on stdout.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
<object>::
|
||||
The name of the object to show.
|
||||
For a more complete list of ways to spell object names, see
|
||||
"SPECIFYING REVISIONS" section in linkgit:git-rev-parse[1].
|
||||
the "SPECIFYING REVISIONS" section in linkgit:git-rev-parse[1].
|
||||
|
||||
-t::
|
||||
Instead of the content, show the object type identified by
|
||||
@ -56,8 +56,8 @@ OPTIONS
|
||||
stdin. May not be combined with any other options or arguments.
|
||||
|
||||
--batch-check::
|
||||
Print the SHA1, type, and size of each object provided on stdin. May not be
|
||||
combined with any other options or arguments.
|
||||
Print the SHA1, type, and size of each object provided on stdin. May not
|
||||
be combined with any other options or arguments.
|
||||
|
||||
OUTPUT
|
||||
------
|
||||
|
@ -14,7 +14,7 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
For every pathname, this command will list if each attr is 'unspecified',
|
||||
For every pathname, this command will list if each attribute is 'unspecified',
|
||||
'set', or 'unset' as a gitattribute on that pathname.
|
||||
|
||||
OPTIONS
|
||||
@ -23,11 +23,11 @@ OPTIONS
|
||||
Read file names from stdin instead of from the command-line.
|
||||
|
||||
-z::
|
||||
Only meaningful with `--stdin`; paths are separated with
|
||||
NUL character instead of LF.
|
||||
Only meaningful with `--stdin`; paths are separated with a
|
||||
NUL character instead of a linefeed character.
|
||||
|
||||
\--::
|
||||
Interpret all preceding arguments as attributes, and all following
|
||||
Interpret all preceding arguments as attributes and all following
|
||||
arguments as path names. If not supplied, only the first argument will
|
||||
be treated as an attribute.
|
||||
|
||||
@ -37,12 +37,12 @@ OUTPUT
|
||||
The output is of the form:
|
||||
<path> COLON SP <attribute> COLON SP <info> LF
|
||||
|
||||
Where <path> is the path of a file being queried, <attribute> is an attribute
|
||||
<path> is the path of a file being queried, <attribute> is an attribute
|
||||
being queried and <info> can be either:
|
||||
|
||||
'unspecified';; when the attribute is not defined for the path.
|
||||
'unset';; when the attribute is defined to false.
|
||||
'set';; when the attribute is defined to true.
|
||||
'unset';; when the attribute is defined as false.
|
||||
'set';; when the attribute is defined as true.
|
||||
<value>;; when a value has been assigned to the attribute.
|
||||
|
||||
EXAMPLES
|
||||
@ -69,7 +69,7 @@ org/example/MyClass.java: diff: java
|
||||
org/example/MyClass.java: myAttr: set
|
||||
---------------
|
||||
|
||||
* Listing attribute for multiple files:
|
||||
* Listing an attribute for multiple files:
|
||||
---------------
|
||||
$ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java
|
||||
org/example/MyClass.java: myAttr: set
|
||||
|
@ -3,7 +3,7 @@ git-check-ref-format(1)
|
||||
|
||||
NAME
|
||||
----
|
||||
git-check-ref-format - Make sure ref name is well formed
|
||||
git-check-ref-format - Ensures that a reference name is well formed
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
@ -11,40 +11,40 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Checks if a given 'refname' is acceptable, and exits non-zero if
|
||||
it is not.
|
||||
Checks if a given 'refname' is acceptable, and exits with a non-zero
|
||||
status if it is not.
|
||||
|
||||
A reference is used in git to specify branches and tags. A
|
||||
branch head is stored under `$GIT_DIR/refs/heads` directory, and
|
||||
a tag is stored under `$GIT_DIR/refs/tags` directory. git
|
||||
imposes the following rules on how refs are named:
|
||||
branch head is stored under the `$GIT_DIR/refs/heads` directory, and
|
||||
a tag is stored under the `$GIT_DIR/refs/tags` directory. git
|
||||
imposes the following rules on how references are named:
|
||||
|
||||
. It can include slash `/` for hierarchical (directory)
|
||||
. They can include slash `/` for hierarchical (directory)
|
||||
grouping, but no slash-separated component can begin with a
|
||||
dot `.`;
|
||||
dot `.`.
|
||||
|
||||
. It cannot have two consecutive dots `..` anywhere;
|
||||
. They cannot have two consecutive dots `..` anywhere.
|
||||
|
||||
. It cannot have ASCII control character (i.e. bytes whose
|
||||
. They cannot have ASCII control characters (i.e. bytes whose
|
||||
values are lower than \040, or \177 `DEL`), space, tilde `~`,
|
||||
caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
|
||||
or open bracket `[` anywhere;
|
||||
or open bracket `[` anywhere.
|
||||
|
||||
. It cannot end with a slash `/`.
|
||||
. They cannot end with a slash `/`.
|
||||
|
||||
These rules makes it easy for shell script based tools to parse
|
||||
refnames, pathname expansion by the shell when a refname is used
|
||||
These rules make it easy for shell script based tools to parse
|
||||
reference names, pathname expansion by the shell when a reference name is used
|
||||
unquoted (by mistake), and also avoids ambiguities in certain
|
||||
refname expressions (see linkgit:git-rev-parse[1]). Namely:
|
||||
reference name expressions (see linkgit:git-rev-parse[1]):
|
||||
|
||||
. double-dot `..` are often used as in `ref1..ref2`, and in some
|
||||
context this notation means `{caret}ref1 ref2` (i.e. not in
|
||||
ref1 and in ref2).
|
||||
. A double-dot `..` is often used as in `ref1..ref2`, and in some
|
||||
contexts this notation means `{caret}ref1 ref2` (i.e. not in
|
||||
`ref1` and in `ref2`).
|
||||
|
||||
. tilde `~` and caret `{caret}` are used to introduce postfix
|
||||
. A tilde `~` and caret `{caret}` are used to introduce the postfix
|
||||
'nth parent' and 'peel onion' operation.
|
||||
|
||||
. colon `:` is used as in `srcref:dstref` to mean "use srcref\'s
|
||||
. A colon `:` is used as in `srcref:dstref` to mean "use srcref\'s
|
||||
value and store it in dstref" in fetch and push operations.
|
||||
It may also be used to select a specific object such as with
|
||||
'git-cat-file': "git cat-file blob v1.3.3:refs.c".
|
||||
|
@ -127,9 +127,13 @@ the conflicted merge in the specified paths.
|
||||
<new_branch>::
|
||||
Name for the new branch.
|
||||
|
||||
<tree-ish>::
|
||||
Tree to checkout from (when paths are given). If not specified,
|
||||
the index will be used.
|
||||
|
||||
<branch>::
|
||||
Branch to checkout; may be any object ID that resolves to a
|
||||
commit. Defaults to HEAD.
|
||||
Branch to checkout (when no paths are given); may be any object
|
||||
ID that resolves to a commit. Defaults to HEAD.
|
||||
+
|
||||
When this parameter names a non-branch (but still a valid commit object),
|
||||
your HEAD becomes 'detached'.
|
||||
@ -191,8 +195,8 @@ $ git checkout hello.c <3>
|
||||
------------
|
||||
+
|
||||
<1> switch branch
|
||||
<2> take out a file out of other commit
|
||||
<3> restore hello.c from HEAD of current branch
|
||||
<2> take a file out of another commit
|
||||
<3> restore hello.c from the index
|
||||
+
|
||||
If you have an unfortunate branch that is named `hello.c`, this
|
||||
step would be confused as an instruction to switch to that branch.
|
||||
|
@ -117,7 +117,7 @@ then the cloned repository will become corrupt.
|
||||
--origin <name>::
|
||||
-o <name>::
|
||||
Instead of using the remote name 'origin' to keep track
|
||||
of the upstream repository, use <name> instead.
|
||||
of the upstream repository, use <name>.
|
||||
|
||||
--upload-pack <upload-pack>::
|
||||
-u <upload-pack>::
|
||||
|
@ -62,7 +62,7 @@ OPTIONS
|
||||
-r <remote>::
|
||||
The git remote to import this CVS repository into.
|
||||
Moves all CVS branches into remotes/<remote>/<branch>
|
||||
akin to the 'git-clone' "--use-separate-remote" option.
|
||||
akin to the way 'git-clone' uses 'origin' by default.
|
||||
|
||||
-o <branch-for-HEAD>::
|
||||
When no remote is specified (via -r) the 'HEAD' branch
|
||||
|
@ -31,6 +31,9 @@ changes, which would normally have no effect. Nevertheless, this may be
|
||||
useful in the future for compensating for some git bugs or such,
|
||||
therefore such a usage is permitted.
|
||||
|
||||
*NOTE*: This command honors `.git/info/grafts`. If you have any grafts
|
||||
defined, running this command will make them permanent.
|
||||
|
||||
*WARNING*! The rewritten history will have different object names for all
|
||||
the objects and will not converge with the original branch. You will not
|
||||
be able to easily push and distribute the rewritten branch on top of the
|
||||
|
@ -39,15 +39,11 @@ There are two ways to specify which commits to operate on.
|
||||
REVISIONS" section in linkgit:git-rev-parse[1]) means the
|
||||
commits in the specified range.
|
||||
|
||||
A single commit, when interpreted as a <revision range>
|
||||
expression, means "everything that leads to that commit", but
|
||||
if you write 'git format-patch <commit>', the previous rule
|
||||
applies to that command line and you do not get "everything
|
||||
since the beginning of the time". If you want to format
|
||||
everything since project inception to one commit, say "git
|
||||
format-patch \--root <commit>" to make it clear that it is the
|
||||
latter case. If you want to format a single commit, you can do
|
||||
this with "git format-patch -1 <commit>".
|
||||
The first rule takes precedence in the case of a single <commit>. To
|
||||
apply the second rule, i.e., format everything since the beginning of
|
||||
history up until <commit>, use the '\--root' option: "git format-patch
|
||||
\--root <commit>". If you want to format only <commit> itself, you
|
||||
can do this with "git format-patch -1 <commit>".
|
||||
|
||||
By default, each output file is numbered sequentially from 1, and uses the
|
||||
first line of the commit message (massaged for pathname safety) as
|
||||
@ -96,7 +92,6 @@ include::diff-options.txt[]
|
||||
--numbered-files::
|
||||
Output file names will be a simple number sequence
|
||||
without the default first line of the commit appended.
|
||||
Mutually exclusive with the --stdout option.
|
||||
|
||||
-k::
|
||||
--keep-subject::
|
||||
@ -170,6 +165,13 @@ not add any suffix.
|
||||
applied. By default the contents of changes in those files are
|
||||
encoded in the patch.
|
||||
|
||||
--root::
|
||||
Treat the revision argument as a <revision range>, even if it
|
||||
is just a single commit (that would normally be treated as a
|
||||
<since>). Note that root commits included in the specified
|
||||
range are always formatted as creation patches, independently
|
||||
of this flag.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
You can specify extra mail header lines to be added to each message
|
||||
|
@ -26,7 +26,7 @@ problem by stashing the refs in a single file,
|
||||
traditional `$GIT_DIR/refs` hierarchy, it is looked up in this
|
||||
file and used if found.
|
||||
|
||||
Subsequent updates to branches always creates new file under
|
||||
Subsequent updates to branches always create new files under
|
||||
`$GIT_DIR/refs` hierarchy.
|
||||
|
||||
A recommended practice to deal with a repository with too many
|
||||
@ -35,7 +35,7 @@ occasionally run `git pack-refs \--prune`. Tags are by
|
||||
definition stationary and are not expected to change. Branch
|
||||
heads will be packed with the initial `pack-refs --all`, but
|
||||
only the currently active branch heads will become unpacked,
|
||||
and next `pack-refs` (without `--all`) will leave them
|
||||
and the next `pack-refs` (without `--all`) will leave them
|
||||
unpacked.
|
||||
|
||||
|
||||
|
@ -63,6 +63,7 @@ OPTIONS
|
||||
are printed when using -l.
|
||||
The default is not to print any annotation lines.
|
||||
If no number is given to `-n`, only the first line is printed.
|
||||
If the tag is not annotated, the commit message is displayed instead.
|
||||
|
||||
-l <pattern>::
|
||||
List tags with names that match the given pattern (or all if no pattern is given).
|
||||
|
@ -60,9 +60,9 @@ same as in `.gitignore` files; see linkgit:gitignore[5].
|
||||
When deciding what attributes are assigned to a path, git
|
||||
consults `$GIT_DIR/info/attributes` file (which has the highest
|
||||
precedence), `.gitattributes` file in the same directory as the
|
||||
path in question, and its parent directories (the further the
|
||||
directory that contains `.gitattributes` is from the path in
|
||||
question, the lower its precedence).
|
||||
path in question, and its parent directories up to the toplevel of the
|
||||
work tree (the further the directory that contains `.gitattributes`
|
||||
is from the path in question, the lower its precedence).
|
||||
|
||||
If you wish to affect only a single repository (i.e., to assign
|
||||
attributes to files that are particular to one user's workflow), then
|
||||
|
@ -31,8 +31,8 @@ precedence, the last matching pattern decides the outcome):
|
||||
|
||||
* Patterns read from a `.gitignore` file in the same directory
|
||||
as the path, or in any parent directory, with patterns in the
|
||||
higher level files (up to the root) being overridden by those in
|
||||
lower level files down to the directory containing the file.
|
||||
higher level files (up to the toplevel of the work tree) being overridden
|
||||
by those in lower level files down to the directory containing the file.
|
||||
These patterns match relative to the location of the
|
||||
`.gitignore` file. A project normally includes such
|
||||
`.gitignore` files in its repository, containing patterns for
|
||||
|
@ -5,22 +5,21 @@ canonical real names and email addresses.
|
||||
|
||||
In the simple form, each line in the file consists of the canonical
|
||||
real name of an author, whitespace, and an email address used in the
|
||||
commit (enclosed by '<' and '>') to map to the name. Thus, looks like
|
||||
this
|
||||
commit (enclosed by '<' and '>') to map to the name. For example:
|
||||
--
|
||||
Proper Name <commit@email.xx>
|
||||
--
|
||||
|
||||
The more complex forms are
|
||||
The more complex forms are:
|
||||
--
|
||||
<proper@email.xx> <commit@email.xx>
|
||||
--
|
||||
which allows mailmap to replace only the email part of a commit, and
|
||||
which allows mailmap to replace only the email part of a commit, and:
|
||||
--
|
||||
Proper Name <proper@email.xx> <commit@email.xx>
|
||||
--
|
||||
which allows mailmap to replace both the name and the email of a
|
||||
commit matching the specified commit email address, and
|
||||
commit matching the specified commit email address, and:
|
||||
--
|
||||
Proper Name <proper@email.xx> Commit Name <commit@email.xx>
|
||||
--
|
||||
@ -47,8 +46,8 @@ Jane Doe <jane@desktop.(none)>
|
||||
Joe R. Developer <joe@example.com>
|
||||
------------
|
||||
|
||||
Note how we don't need an entry for <jane@laptop.(none)>, because the
|
||||
real name of that author is correct already.
|
||||
Note how there is no need for an entry for <jane@laptop.(none)>, because the
|
||||
real name of that author is already correct.
|
||||
|
||||
Example 2: Your repository contains commits from the following
|
||||
authors:
|
||||
@ -62,7 +61,7 @@ claus <me@company.xx>
|
||||
CTO <cto@coompany.xx>
|
||||
------------
|
||||
|
||||
Then, you might want a `.mailmap` file looking like:
|
||||
Then you might want a `.mailmap` file that looks like:
|
||||
------------
|
||||
<cto@company.xx> <cto@coompany.xx>
|
||||
Some Dude <some@dude.xx> nick1 <bugs@company.xx>
|
||||
@ -72,4 +71,4 @@ Santa Claus <santa.claus@northpole.xx> <me@company.xx>
|
||||
------------
|
||||
|
||||
Use hash '#' for comments that are either on their own line, or after
|
||||
the email address.
|
||||
the email address.
|
||||
|
@ -148,22 +148,22 @@ outputting that information, if desired.
|
||||
------------
|
||||
*
|
||||
*
|
||||
M
|
||||
*
|
||||
|\
|
||||
* |
|
||||
| | *
|
||||
| \ \
|
||||
| \ \
|
||||
M-. \ \
|
||||
*-. \ \
|
||||
|\ \ \ \
|
||||
| | * | |
|
||||
| | | | | *
|
||||
| | | | | *
|
||||
| | | | | M
|
||||
| | | | | *
|
||||
| | | | | |\
|
||||
| | | | | | *
|
||||
| * | | | | |
|
||||
| | | | | M \
|
||||
| | | | | * \
|
||||
| | | | | |\ |
|
||||
| | | | * | | |
|
||||
| | | | * | | |
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.2.1
|
||||
DEF_VER=v1.6.2.3
|
||||
|
||||
LF='
|
||||
'
|
||||
|
2
RelNotes
2
RelNotes
@ -1 +1 @@
|
||||
Documentation/RelNotes-1.6.2.1.txt
|
||||
Documentation/RelNotes-1.6.2.3.txt
|
@ -2263,6 +2263,10 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
||||
parse_done:
|
||||
argc = parse_options_end(&ctx);
|
||||
|
||||
if (revs_file && read_ancestry(revs_file))
|
||||
die("reading graft file %s failed: %s",
|
||||
revs_file, strerror(errno));
|
||||
|
||||
if (cmd_is_annotate)
|
||||
output_option |= OUTPUT_ANNOTATE_COMPAT;
|
||||
|
||||
@ -2404,10 +2408,6 @@ parse_done:
|
||||
sb.ent = ent;
|
||||
sb.path = path;
|
||||
|
||||
if (revs_file && read_ancestry(revs_file))
|
||||
die("reading graft file %s failed: %s",
|
||||
revs_file, strerror(errno));
|
||||
|
||||
read_mailmap(&mailmap, NULL);
|
||||
|
||||
if (!incremental)
|
||||
|
@ -171,7 +171,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
|
||||
ret = 1;
|
||||
} else {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
printf("Deleted %sbranch %s (%s).\n", remote,
|
||||
printf("Deleted %sbranch %s (was %s).\n", remote,
|
||||
bname.buf,
|
||||
find_unique_abbrev(sha1, DEFAULT_ABBREV));
|
||||
strbuf_addf(&buf, "branch.%s", bname.buf);
|
||||
|
@ -501,10 +501,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
|
||||
create_symref("HEAD", new->path, msg.buf);
|
||||
if (!opts->quiet) {
|
||||
if (old->path && !strcmp(new->path, old->path))
|
||||
fprintf(stderr, "Already on \"%s\"\n",
|
||||
fprintf(stderr, "Already on '%s'\n",
|
||||
new->name);
|
||||
else
|
||||
fprintf(stderr, "Switched to%s branch \"%s\"\n",
|
||||
fprintf(stderr, "Switched to%s branch '%s'\n",
|
||||
opts->new_branch ? " a new" : "",
|
||||
new->name);
|
||||
}
|
||||
@ -513,7 +513,7 @@ static void update_refs_for_switch(struct checkout_opts *opts,
|
||||
REF_NODEREF, DIE_ON_ERR);
|
||||
if (!opts->quiet) {
|
||||
if (old->path)
|
||||
fprintf(stderr, "Note: moving to \"%s\" which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n git checkout -b <new_branch_name>\n", new->name);
|
||||
fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n git checkout -b <new_branch_name>\n", new->name);
|
||||
describe_detached_head("HEAD is now at", new->commit);
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
|
||||
const char **pathspec = NULL;
|
||||
|
||||
if (interactive) {
|
||||
interactive_add(argc, argv, prefix);
|
||||
if (interactive_add(argc, argv, prefix) != 0)
|
||||
die("interactive add failed");
|
||||
if (read_cache_preload(NULL) < 0)
|
||||
die("index file corrupt");
|
||||
commit_style = COMMIT_AS_IS;
|
||||
|
@ -60,7 +60,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
|
||||
hex[40] = 0;
|
||||
if (get_sha1_hex(hex, sha1))
|
||||
die("internal error");
|
||||
if (has_sha1_pack(sha1, NULL))
|
||||
if (has_sha1_pack(sha1))
|
||||
(*packed_loose)++;
|
||||
}
|
||||
}
|
||||
|
@ -636,6 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
||||
else
|
||||
remote = remote_get(argv[0]);
|
||||
|
||||
if (!remote)
|
||||
die("Where do you want to fetch from today?");
|
||||
|
||||
transport = transport_get(remote, remote->url[0]);
|
||||
if (verbosity >= 2)
|
||||
transport->verbose = 1;
|
||||
@ -648,9 +651,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
||||
if (depth)
|
||||
set_option(TRANS_OPT_DEPTH, depth);
|
||||
|
||||
if (!transport->url)
|
||||
die("Where do you want to fetch from today?");
|
||||
|
||||
if (argc > 1) {
|
||||
int j = 0;
|
||||
refs = xcalloc(argc + 1, sizeof(const char *));
|
||||
|
@ -160,7 +160,7 @@ static void check_reachable_object(struct object *obj)
|
||||
* do a full fsck
|
||||
*/
|
||||
if (!obj->parsed) {
|
||||
if (has_sha1_pack(obj->sha1, NULL))
|
||||
if (has_sha1_pack(obj->sha1))
|
||||
return; /* it is in pack - forget about it */
|
||||
printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
|
@ -195,6 +195,8 @@ static int create_default_files(const char *template_path)
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
is_bare_repository_cfg = init_is_bare_repository;
|
||||
|
||||
/* reading existing config may have overwrote it */
|
||||
if (init_shared_repository != -1)
|
||||
shared_repository = init_shared_repository;
|
||||
|
||||
@ -313,12 +315,15 @@ int init_db(const char *template_dir, unsigned int flags)
|
||||
* and compatibility values for PERM_GROUP and
|
||||
* PERM_EVERYBODY.
|
||||
*/
|
||||
if (shared_repository == PERM_GROUP)
|
||||
if (shared_repository < 0)
|
||||
/* force to the mode value */
|
||||
sprintf(buf, "0%o", -shared_repository);
|
||||
else if (shared_repository == PERM_GROUP)
|
||||
sprintf(buf, "%d", OLD_PERM_GROUP);
|
||||
else if (shared_repository == PERM_EVERYBODY)
|
||||
sprintf(buf, "%d", OLD_PERM_EVERYBODY);
|
||||
else
|
||||
sprintf(buf, "0%o", shared_repository);
|
||||
die("oops");
|
||||
git_config_set("core.sharedrepository", buf);
|
||||
git_config_set("receive.denyNonFastforwards", "true");
|
||||
}
|
||||
@ -398,6 +403,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
usage(init_db_usage);
|
||||
}
|
||||
|
||||
if (init_shared_repository != -1)
|
||||
shared_repository = init_shared_repository;
|
||||
|
||||
/*
|
||||
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
|
||||
* without --bare. Catch the error early.
|
||||
|
@ -917,8 +917,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
die ("-n and -k are mutually exclusive.");
|
||||
if (keep_subject && subject_prefix)
|
||||
die ("--subject-prefix and -k are mutually exclusive.");
|
||||
if (numbered_files && use_stdout)
|
||||
die ("--numbered-files and --stdout are mutually exclusive.");
|
||||
|
||||
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
||||
if (argc > 1)
|
||||
|
@ -419,6 +419,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
|
||||
show_deleted = 1;
|
||||
require_work_tree = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-m") || !strcmp(arg, "--modified")) {
|
||||
|
@ -1293,7 +1293,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
|
||||
max_size = trg_entry->delta_size;
|
||||
ref_depth = trg->depth;
|
||||
}
|
||||
max_size = max_size * (max_depth - src->depth) /
|
||||
max_size = (uint64_t)max_size * (max_depth - src->depth) /
|
||||
(max_depth - ref_depth + 1);
|
||||
if (max_size == 0)
|
||||
return 0;
|
||||
@ -1912,6 +1912,8 @@ static void show_object(struct object_array_entry *p)
|
||||
add_preferred_base_object(p->name);
|
||||
add_object_entry(p->item->sha1, p->item->type, p->name, 0);
|
||||
p->item->flags |= OBJECT_ADDED;
|
||||
free((char *)p->name);
|
||||
p->name = NULL;
|
||||
}
|
||||
|
||||
static void show_edge(struct commit *commit)
|
||||
@ -1966,11 +1968,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
|
||||
const unsigned char *sha1;
|
||||
struct object *o;
|
||||
|
||||
for (i = 0; i < revs->num_ignore_packed; i++) {
|
||||
if (matches_pack_name(p, revs->ignore_packed[i]))
|
||||
break;
|
||||
}
|
||||
if (revs->num_ignore_packed <= i)
|
||||
if (!p->pack_local || p->pack_keep)
|
||||
continue;
|
||||
if (open_pack_index(p))
|
||||
die("cannot open pack index");
|
||||
@ -1999,6 +1997,29 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
|
||||
free(in_pack.array);
|
||||
}
|
||||
|
||||
static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
|
||||
{
|
||||
static struct packed_git *last_found = (void *)1;
|
||||
struct packed_git *p;
|
||||
|
||||
p = (last_found != (void *)1) ? last_found : packed_git;
|
||||
|
||||
while (p) {
|
||||
if ((!p->pack_local || p->pack_keep) &&
|
||||
find_pack_entry_one(sha1, p)) {
|
||||
last_found = p;
|
||||
return 1;
|
||||
}
|
||||
if (p == last_found)
|
||||
p = packed_git;
|
||||
else
|
||||
p = p->next;
|
||||
if (p == last_found)
|
||||
p = p->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void loosen_unused_packed_objects(struct rev_info *revs)
|
||||
{
|
||||
struct packed_git *p;
|
||||
@ -2006,11 +2027,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
|
||||
const unsigned char *sha1;
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (i = 0; i < revs->num_ignore_packed; i++) {
|
||||
if (matches_pack_name(p, revs->ignore_packed[i]))
|
||||
break;
|
||||
}
|
||||
if (revs->num_ignore_packed <= i)
|
||||
if (!p->pack_local || p->pack_keep)
|
||||
continue;
|
||||
|
||||
if (open_pack_index(p))
|
||||
@ -2018,7 +2035,8 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
|
||||
|
||||
for (i = 0; i < p->num_objects; i++) {
|
||||
sha1 = nth_packed_object_sha1(p, i);
|
||||
if (!locate_object_entry(sha1))
|
||||
if (!locate_object_entry(sha1) &&
|
||||
!has_sha1_pack_kept_or_nonlocal(sha1))
|
||||
if (force_object_loose(sha1, p->mtime))
|
||||
die("unable to force loose object");
|
||||
}
|
||||
@ -2208,7 +2226,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--unpacked", arg) ||
|
||||
!prefixcmp(arg, "--unpacked=") ||
|
||||
!strcmp("--reflog", arg) ||
|
||||
!strcmp("--all", arg)) {
|
||||
use_internal_rev_list = 1;
|
||||
|
@ -23,7 +23,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
|
||||
memcpy(hex+2, de->d_name, 38);
|
||||
if (get_sha1_hex(hex, sha1))
|
||||
continue;
|
||||
if (!has_sha1_pack(sha1, NULL))
|
||||
if (!has_sha1_pack(sha1))
|
||||
continue;
|
||||
memcpy(pathname + len, de->d_name, 38);
|
||||
if (opts & DRY_RUN)
|
||||
|
@ -53,8 +53,11 @@ static int do_push(const char *repo, int flags)
|
||||
int i, errs;
|
||||
struct remote *remote = remote_get(repo);
|
||||
|
||||
if (!remote)
|
||||
die("bad repository '%s'", repo);
|
||||
if (!remote) {
|
||||
if (repo)
|
||||
die("bad repository '%s'", repo);
|
||||
die("No destination configured to push to.");
|
||||
}
|
||||
|
||||
if (remote->mirror)
|
||||
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
|
||||
|
6
cache.h
6
cache.h
@ -613,7 +613,8 @@ enum sharedrepo {
|
||||
PERM_EVERYBODY = 0664,
|
||||
};
|
||||
int git_config_perm(const char *var, const char *value);
|
||||
int adjust_shared_perm(const char *path);
|
||||
int set_shared_perm(const char *path, int mode);
|
||||
#define adjust_shared_perm(path) set_shared_perm((path), 0)
|
||||
int safe_create_leading_directories(char *path);
|
||||
int safe_create_leading_directories_const(const char *path);
|
||||
char *enter_repo(char *path, int strict);
|
||||
@ -644,7 +645,7 @@ extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned l
|
||||
|
||||
extern int move_temp_to_file(const char *tmpfile, const char *filename);
|
||||
|
||||
extern int has_sha1_pack(const unsigned char *sha1, const char **ignore);
|
||||
extern int has_sha1_pack(const unsigned char *sha1);
|
||||
extern int has_sha1_file(const unsigned char *sha1);
|
||||
extern int has_loose_object_nonlocal(const unsigned char *sha1);
|
||||
|
||||
@ -839,7 +840,6 @@ extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsign
|
||||
extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
||||
extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
|
||||
extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
|
||||
extern int matches_pack_name(struct packed_git *p, const char *name);
|
||||
|
||||
/* Dumb servers support */
|
||||
extern int update_server_info(int);
|
||||
|
@ -5,6 +5,8 @@ void *gitmemmem(const void *haystack, size_t haystack_len,
|
||||
{
|
||||
const char *begin = haystack;
|
||||
const char *last_possible = begin + haystack_len - needle_len;
|
||||
const char *tail = needle;
|
||||
char point;
|
||||
|
||||
/*
|
||||
* The first occurrence of the empty string is deemed to occur at
|
||||
@ -20,8 +22,9 @@ void *gitmemmem(const void *haystack, size_t haystack_len,
|
||||
if (haystack_len < needle_len)
|
||||
return NULL;
|
||||
|
||||
point = *tail++;
|
||||
for (; begin <= last_possible; begin++) {
|
||||
if (!memcmp(begin, needle, needle_len))
|
||||
if (*begin == point && !memcmp(begin + 1, tail, needle_len - 1))
|
||||
return (void *)begin;
|
||||
}
|
||||
|
||||
|
@ -1005,7 +1005,7 @@ _git_log ()
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local g="$(git rev-parse --git-dir 2>/dev/null)"
|
||||
local merge=""
|
||||
if [ -f $g/MERGE_HEAD ]; then
|
||||
if [ -f "$g/MERGE_HEAD" ]; then
|
||||
merge="--merge"
|
||||
fi
|
||||
case "$cur" in
|
||||
@ -1843,7 +1843,7 @@ _gitk ()
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local g="$(git rev-parse --git-dir 2>/dev/null)"
|
||||
local merge=""
|
||||
if [ -f $g/MERGE_HEAD ]; then
|
||||
if [ -f "$g/MERGE_HEAD" ]; then
|
||||
merge="--merge"
|
||||
fi
|
||||
case "$cur" in
|
||||
|
@ -44,7 +44,8 @@ for zipfile in argv[1:]:
|
||||
common_prefix = name[:name.rfind('/') + 1]
|
||||
else:
|
||||
while not name.startswith(common_prefix):
|
||||
common_prefix = name[:name.rfind('/') + 1]
|
||||
last_slash = common_prefix[:-1].rfind('/') + 1
|
||||
common_prefix = common_prefix[:last_slash]
|
||||
|
||||
mark[name] = ':' + str(next_mark)
|
||||
next_mark += 1
|
||||
|
@ -201,8 +201,6 @@ void diff_no_index(struct rev_info *revs,
|
||||
no_index ? "--no-index" : "[--no-index]");
|
||||
|
||||
diff_setup(&revs->diffopt);
|
||||
if (!revs->diffopt.output_format)
|
||||
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||
for (i = 1; i < argc - 2; ) {
|
||||
int j;
|
||||
if (!strcmp(argv[i], "--no-index"))
|
||||
@ -248,6 +246,8 @@ void diff_no_index(struct rev_info *revs,
|
||||
revs->diffopt.paths = argv + argc - 2;
|
||||
revs->diffopt.nr_paths = 2;
|
||||
revs->diffopt.skip_stat_unmatch = 1;
|
||||
if (!revs->diffopt.output_format)
|
||||
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||
|
||||
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
|
||||
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
|
||||
|
25
diff.c
25
diff.c
@ -1759,7 +1759,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
||||
struct stat st;
|
||||
int pos, len;
|
||||
|
||||
/* We do not read the cache ourselves here, because the
|
||||
/*
|
||||
* We do not read the cache ourselves here, because the
|
||||
* benchmark with my previous version that always reads cache
|
||||
* shows that it makes things worse for diff-tree comparing
|
||||
* two linux-2.6 kernel trees in an already checked out work
|
||||
@ -1783,7 +1784,7 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
||||
* objects however would tend to be slower as they need
|
||||
* to be individually opened and inflated.
|
||||
*/
|
||||
if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(sha1, NULL))
|
||||
if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(sha1))
|
||||
return 0;
|
||||
|
||||
len = strlen(name);
|
||||
@ -1799,6 +1800,13 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
||||
if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If ce is marked as "assume unchanged", there is no
|
||||
* guarantee that work tree matches what we are looking for.
|
||||
*/
|
||||
if (ce->ce_flags & CE_VALID)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If ce matches the file in the work tree, we can reuse it.
|
||||
*/
|
||||
@ -1948,17 +1956,23 @@ void diff_free_filespec_data(struct diff_filespec *s)
|
||||
s->cnt_data = NULL;
|
||||
}
|
||||
|
||||
static void prep_temp_blob(struct diff_tempfile *temp,
|
||||
static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
|
||||
void *blob,
|
||||
unsigned long size,
|
||||
const unsigned char *sha1,
|
||||
int mode)
|
||||
{
|
||||
int fd;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX");
|
||||
if (fd < 0)
|
||||
die("unable to create temp-file: %s", strerror(errno));
|
||||
if (convert_to_working_tree(path,
|
||||
(const char *)blob, (size_t)size, &buf)) {
|
||||
blob = buf.buf;
|
||||
size = buf.len;
|
||||
}
|
||||
if (write_in_full(fd, blob, size) != size)
|
||||
die("unable to write temp-file");
|
||||
close(fd);
|
||||
@ -1966,6 +1980,7 @@ static void prep_temp_blob(struct diff_tempfile *temp,
|
||||
strcpy(temp->hex, sha1_to_hex(sha1));
|
||||
temp->hex[40] = 0;
|
||||
sprintf(temp->mode, "%06o", mode);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
static struct diff_tempfile *prepare_temp_file(const char *name,
|
||||
@ -2006,7 +2021,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
|
||||
die("readlink(%s)", name);
|
||||
if (ret == sizeof(buf))
|
||||
die("symlink too long: %s", name);
|
||||
prep_temp_blob(temp, buf, ret,
|
||||
prep_temp_blob(name, temp, buf, ret,
|
||||
(one->sha1_valid ?
|
||||
one->sha1 : null_sha1),
|
||||
(one->sha1_valid ?
|
||||
@ -2032,7 +2047,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
|
||||
else {
|
||||
if (diff_populate_filespec(one, 0))
|
||||
die("cannot read data blob for %s", one->path);
|
||||
prep_temp_blob(temp, one->data, one->size,
|
||||
prep_temp_blob(name, temp, one->data, one->size,
|
||||
one->sha1, one->mode);
|
||||
}
|
||||
return temp;
|
||||
|
@ -10,7 +10,7 @@ static unsigned int contains(struct diff_filespec *one,
|
||||
regex_t *regexp)
|
||||
{
|
||||
unsigned int cnt;
|
||||
unsigned long offset, sz;
|
||||
unsigned long sz;
|
||||
const char *data;
|
||||
if (diff_populate_filespec(one, 0))
|
||||
return 0;
|
||||
@ -25,23 +25,23 @@ static unsigned int contains(struct diff_filespec *one,
|
||||
regmatch_t regmatch;
|
||||
int flags = 0;
|
||||
|
||||
assert(data[sz] == '\0');
|
||||
while (*data && !regexec(regexp, data, 1, ®match, flags)) {
|
||||
flags |= REG_NOTBOL;
|
||||
data += regmatch.rm_so;
|
||||
if (*data) data++;
|
||||
data += regmatch.rm_eo;
|
||||
if (*data && regmatch.rm_so == regmatch.rm_eo)
|
||||
data++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
} else { /* Classic exact string match */
|
||||
/* Yes, I've heard of strstr(), but the thing is *data may
|
||||
* not be NUL terminated. Sue me.
|
||||
*/
|
||||
for (offset = 0; offset + len <= sz; offset++) {
|
||||
/* we count non-overlapping occurrences of needle */
|
||||
if (!memcmp(needle, data + offset, len)) {
|
||||
offset += len - 1;
|
||||
cnt++;
|
||||
}
|
||||
while (sz) {
|
||||
const char *found = memmem(data, sz, needle, len);
|
||||
if (!found)
|
||||
break;
|
||||
sz -= found - data + len;
|
||||
data = found + len;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
diff_free_filespec_data(one);
|
||||
|
@ -61,6 +61,10 @@ const char *git_extract_argv0_path(const char *argv0)
|
||||
void git_set_argv_exec_path(const char *exec_path)
|
||||
{
|
||||
argv_exec_path = exec_path;
|
||||
/*
|
||||
* Propagate this setting to external programs.
|
||||
*/
|
||||
setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -902,9 +902,6 @@ static char *keep_pack(char *curr_index_name)
|
||||
static const char *keep_msg = "fast-import";
|
||||
int keep_fd;
|
||||
|
||||
chmod(pack_data->pack_name, 0444);
|
||||
chmod(curr_index_name, 0444);
|
||||
|
||||
keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
|
||||
if (keep_fd < 0)
|
||||
die("cannot create keep file");
|
||||
|
42
git-pull.sh
42
git-pull.sh
@ -90,23 +90,31 @@ error_on_no_merge_candidates () {
|
||||
|
||||
curr_branch=${curr_branch#refs/heads/}
|
||||
|
||||
echo "You asked me to pull without telling me which branch you"
|
||||
echo "want to merge with, and 'branch.${curr_branch}.merge' in"
|
||||
echo "your configuration file does not tell me either. Please"
|
||||
echo "name which branch you want to merge on the command line and"
|
||||
echo "try again (e.g. 'git pull <repository> <refspec>')."
|
||||
echo "See git-pull(1) for details on the refspec."
|
||||
echo
|
||||
echo "If you often merge with the same branch, you may want to"
|
||||
echo "configure the following variables in your configuration"
|
||||
echo "file:"
|
||||
echo
|
||||
echo " branch.${curr_branch}.remote = <nickname>"
|
||||
echo " branch.${curr_branch}.merge = <remote-ref>"
|
||||
echo " remote.<nickname>.url = <url>"
|
||||
echo " remote.<nickname>.fetch = <refspec>"
|
||||
echo
|
||||
echo "See git-config(1) for details."
|
||||
if [ -z "$curr_branch" ]; then
|
||||
echo "You are not currently on a branch, so I cannot use any"
|
||||
echo "'branch.<branchname>.merge' in your configuration file."
|
||||
echo "Please specify which branch you want to merge on the command"
|
||||
echo "line and try again (e.g. 'git pull <repository> <refspec>')."
|
||||
echo "See git-pull(1) for details."
|
||||
else
|
||||
echo "You asked me to pull without telling me which branch you"
|
||||
echo "want to merge with, and 'branch.${curr_branch}.merge' in"
|
||||
echo "your configuration file does not tell me either. Please"
|
||||
echo "specify which branch you want to merge on the command line and"
|
||||
echo "try again (e.g. 'git pull <repository> <refspec>')."
|
||||
echo "See git-pull(1) for details."
|
||||
echo
|
||||
echo "If you often merge with the same branch, you may want to"
|
||||
echo "configure the following variables in your configuration"
|
||||
echo "file:"
|
||||
echo
|
||||
echo " branch.${curr_branch}.remote = <nickname>"
|
||||
echo " branch.${curr_branch}.merge = <remote-ref>"
|
||||
echo " remote.<nickname>.url = <url>"
|
||||
echo " remote.<nickname>.fetch = <refspec>"
|
||||
echo
|
||||
echo "See git-config(1) for details."
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@ case ",$all_into_one," in
|
||||
args='--unpacked --incremental'
|
||||
;;
|
||||
,t,)
|
||||
args= existing=
|
||||
if [ -d "$PACKDIR" ]; then
|
||||
for e in `cd "$PACKDIR" && find . -type f -name '*.pack' \
|
||||
| sed -e 's/^\.\///' -e 's/\.pack$//'`
|
||||
@ -67,11 +68,10 @@ case ",$all_into_one," in
|
||||
if [ -e "$PACKDIR/$e.keep" ]; then
|
||||
: keep
|
||||
else
|
||||
args="$args --unpacked=$e.pack"
|
||||
existing="$existing $e"
|
||||
fi
|
||||
done
|
||||
if test -n "$args" -a -n "$unpack_unreachable" -a \
|
||||
if test -n "$existing" -a -n "$unpack_unreachable" -a \
|
||||
-n "$remove_redundant"
|
||||
then
|
||||
args="$args $unpack_unreachable"
|
||||
@ -181,5 +181,5 @@ fi
|
||||
|
||||
case "$no_update_info" in
|
||||
t) : ;;
|
||||
*) git-update-server-info ;;
|
||||
*) git update-server-info ;;
|
||||
esac
|
||||
|
@ -821,7 +821,7 @@ Date: $date
|
||||
Message-Id: $message_id
|
||||
X-Mailer: git-send-email $gitversion
|
||||
";
|
||||
if ($thread && $reply_to) {
|
||||
if ($reply_to) {
|
||||
|
||||
$header .= "In-Reply-To: $reply_to\n";
|
||||
$header .= "References: $references\n";
|
||||
|
@ -5,7 +5,7 @@
|
||||
# Copyright (c) 2007 Lars Hjemli
|
||||
|
||||
USAGE="[--quiet] [--cached] \
|
||||
[add <repo> [-b branch] <path>]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit <n>] [<commit>]] \
|
||||
[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit <n>] [<commit>]] \
|
||||
[--] [<path>...]|[foreach <command>]|[sync [--] [<path>...]]"
|
||||
OPTIONS_SPEC=
|
||||
. git-sh-setup
|
||||
@ -167,9 +167,18 @@ cmd_add()
|
||||
;;
|
||||
esac
|
||||
|
||||
# strip trailing slashes from path
|
||||
path=$(echo "$path" | sed -e 's|/*$||')
|
||||
|
||||
# normalize path:
|
||||
# multiple //; leading ./; /./; /../; trailing /
|
||||
path=$(printf '%s/\n' "$path" |
|
||||
sed -e '
|
||||
s|//*|/|g
|
||||
s|^\(\./\)*||
|
||||
s|/\./|/|g
|
||||
:start
|
||||
s|\([^/]*\)/\.\./||
|
||||
tstart
|
||||
s|/*$||
|
||||
')
|
||||
git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
|
||||
die "'$path' already exists in the index"
|
||||
|
||||
|
15
git-svn.perl
15
git-svn.perl
@ -3384,15 +3384,18 @@ sub delete_entry {
|
||||
return undef if ($gpath eq '');
|
||||
|
||||
# remove entire directories.
|
||||
if (command('ls-tree', $self->{c}, '--', $gpath) =~ /^040000 tree/) {
|
||||
my ($tree) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
|
||||
=~ /\A040000 tree ([a-f\d]{40})\t\Q$gpath\E\0/);
|
||||
if ($tree) {
|
||||
my ($ls, $ctx) = command_output_pipe(qw/ls-tree
|
||||
-r --name-only -z/,
|
||||
$self->{c}, '--', $gpath);
|
||||
$tree);
|
||||
local $/ = "\0";
|
||||
while (<$ls>) {
|
||||
chomp;
|
||||
$self->{gii}->remove($_);
|
||||
print "\tD\t$_\n" unless $::_q;
|
||||
my $rmpath = "$gpath/$_";
|
||||
$self->{gii}->remove($rmpath);
|
||||
print "\tD\t$rmpath\n" unless $::_q;
|
||||
}
|
||||
print "\tD\t$gpath/\n" unless $::_q;
|
||||
command_close_pipe($ls, $ctx);
|
||||
@ -3411,8 +3414,8 @@ sub open_file {
|
||||
goto out if is_path_ignored($path);
|
||||
|
||||
my $gpath = $self->git_path($path);
|
||||
($mode, $blob) = (command('ls-tree', $self->{c}, '--', $gpath)
|
||||
=~ /^(\d{6}) blob ([a-f\d]{40})\t/);
|
||||
($mode, $blob) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
|
||||
=~ /\A(\d{6}) blob ([a-f\d]{40})\t\Q$gpath\E\0/);
|
||||
unless (defined $mode && defined $blob) {
|
||||
die "$path was not found in commit $self->{c} (r$rev)\n";
|
||||
}
|
||||
|
@ -748,7 +748,6 @@ static void finish_request(struct transfer_request *request)
|
||||
aborted = 1;
|
||||
}
|
||||
} else if (request->state == RUN_FETCH_LOOSE) {
|
||||
fchmod(request->local_fileno, 0444);
|
||||
close(request->local_fileno); request->local_fileno = -1;
|
||||
|
||||
if (request->curl_result != CURLE_OK &&
|
||||
|
@ -231,7 +231,6 @@ static void finish_object_request(struct object_request *obj_req)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
fchmod(obj_req->local, 0444);
|
||||
close(obj_req->local); obj_req->local = -1;
|
||||
|
||||
if (obj_req->http_code == 416) {
|
||||
|
@ -823,8 +823,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
}
|
||||
if (move_temp_to_file(curr_pack_name, final_pack_name))
|
||||
die("cannot store pack file");
|
||||
}
|
||||
if (from_stdin)
|
||||
} else if (from_stdin)
|
||||
chmod(final_pack_name, 0444);
|
||||
|
||||
if (final_index_name != curr_index_name) {
|
||||
@ -835,8 +834,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
}
|
||||
if (move_temp_to_file(curr_index_name, final_index_name))
|
||||
die("cannot store index file");
|
||||
}
|
||||
chmod(final_index_name, 0444);
|
||||
} else
|
||||
chmod(final_index_name, 0444);
|
||||
|
||||
if (!from_stdin) {
|
||||
printf("%s\n", sha1_to_hex(sha1));
|
||||
|
@ -23,7 +23,6 @@ static void process_blob(struct rev_info *revs,
|
||||
if (obj->flags & (UNINTERESTING | SEEN))
|
||||
return;
|
||||
obj->flags |= SEEN;
|
||||
name = xstrdup(name);
|
||||
add_object(obj, p, path, name);
|
||||
}
|
||||
|
||||
@ -78,7 +77,6 @@ static void process_tree(struct rev_info *revs,
|
||||
if (parse_tree(tree) < 0)
|
||||
die("bad tree object %s", sha1_to_hex(obj->sha1));
|
||||
obj->flags |= SEEN;
|
||||
name = xstrdup(name);
|
||||
add_object(obj, p, path, name);
|
||||
me.up = path;
|
||||
me.elem = name;
|
||||
|
@ -50,6 +50,15 @@ static void add_mapping(struct string_list *map,
|
||||
{
|
||||
struct mailmap_entry *me;
|
||||
int index;
|
||||
char *p;
|
||||
|
||||
if (old_email)
|
||||
for (p = old_email; *p; p++)
|
||||
*p = tolower(*p);
|
||||
if (new_email)
|
||||
for (p = new_email; *p; p++)
|
||||
*p = tolower(*p);
|
||||
|
||||
if (old_email == NULL) {
|
||||
old_email = new_email;
|
||||
new_email = NULL;
|
||||
|
53
path.c
53
path.c
@ -311,36 +311,49 @@ char *enter_repo(char *path, int strict)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int adjust_shared_perm(const char *path)
|
||||
int set_shared_perm(const char *path, int mode)
|
||||
{
|
||||
struct stat st;
|
||||
int mode;
|
||||
int tweak, shared, orig_mode;
|
||||
|
||||
if (!shared_repository)
|
||||
if (!shared_repository) {
|
||||
if (mode)
|
||||
return chmod(path, mode & ~S_IFMT);
|
||||
return 0;
|
||||
if (lstat(path, &st) < 0)
|
||||
return -1;
|
||||
mode = st.st_mode;
|
||||
|
||||
if (shared_repository) {
|
||||
int tweak = shared_repository;
|
||||
if (!(mode & S_IWUSR))
|
||||
tweak &= ~0222;
|
||||
mode |= tweak;
|
||||
} else {
|
||||
/* Preserve old PERM_UMASK behaviour */
|
||||
if (mode & S_IWUSR)
|
||||
mode |= S_IWGRP;
|
||||
}
|
||||
if (!mode) {
|
||||
if (lstat(path, &st) < 0)
|
||||
return -1;
|
||||
mode = st.st_mode;
|
||||
orig_mode = mode;
|
||||
} else
|
||||
orig_mode = 0;
|
||||
if (shared_repository < 0)
|
||||
shared = -shared_repository;
|
||||
else
|
||||
shared = shared_repository;
|
||||
tweak = shared;
|
||||
|
||||
if (!(mode & S_IWUSR))
|
||||
tweak &= ~0222;
|
||||
if (mode & S_IXUSR)
|
||||
/* Copy read bits to execute bits */
|
||||
tweak |= (tweak & 0444) >> 2;
|
||||
if (shared_repository < 0)
|
||||
mode = (mode & ~0777) | tweak;
|
||||
else
|
||||
mode |= tweak;
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
mode |= FORCE_DIR_SET_GID;
|
||||
|
||||
/* Copy read bits to execute bits */
|
||||
mode |= (shared_repository & 0444) >> 2;
|
||||
mode |= (shared & 0444) >> 2;
|
||||
mode |= FORCE_DIR_SET_GID;
|
||||
}
|
||||
|
||||
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
|
||||
if (((shared_repository < 0
|
||||
? (orig_mode & (FORCE_DIR_SET_GID | 0777))
|
||||
: (orig_mode & mode)) != mode) &&
|
||||
chmod(path, (mode & ~S_IFMT)) < 0)
|
||||
return -2;
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ static void process_tree(struct tree *tree,
|
||||
obj->flags |= SEEN;
|
||||
if (parse_tree(tree) < 0)
|
||||
die("bad tree object %s", sha1_to_hex(obj->sha1));
|
||||
name = xstrdup(name);
|
||||
add_object(obj, p, path, name);
|
||||
me.up = path;
|
||||
me.elem = name;
|
||||
|
15
remote.c
15
remote.c
@ -38,6 +38,7 @@ static int branches_nr;
|
||||
|
||||
static struct branch *current_branch;
|
||||
static const char *default_remote_name;
|
||||
static int explicit_default_remote_name;
|
||||
|
||||
static struct rewrite **rewrite;
|
||||
static int rewrite_alloc;
|
||||
@ -330,8 +331,10 @@ static int handle_config(const char *key, const char *value, void *cb)
|
||||
if (!value)
|
||||
return config_error_nonbool(key);
|
||||
branch->remote_name = xstrdup(value);
|
||||
if (branch == current_branch)
|
||||
if (branch == current_branch) {
|
||||
default_remote_name = branch->remote_name;
|
||||
explicit_default_remote_name = 1;
|
||||
}
|
||||
} else if (!strcmp(subkey, ".merge")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(key);
|
||||
@ -643,10 +646,16 @@ static int valid_remote_nick(const char *name)
|
||||
struct remote *remote_get(const char *name)
|
||||
{
|
||||
struct remote *ret;
|
||||
int name_given = 0;
|
||||
|
||||
read_config();
|
||||
if (!name)
|
||||
if (name)
|
||||
name_given = 1;
|
||||
else {
|
||||
name = default_remote_name;
|
||||
name_given = explicit_default_remote_name;
|
||||
}
|
||||
|
||||
ret = make_remote(name, 0);
|
||||
if (valid_remote_nick(name)) {
|
||||
if (!ret->url)
|
||||
@ -654,7 +663,7 @@ struct remote *remote_get(const char *name)
|
||||
if (!ret->url)
|
||||
read_branches_file(ret);
|
||||
}
|
||||
if (!ret->url)
|
||||
if (name_given && !ret->url)
|
||||
add_url_alias(ret, name);
|
||||
if (!ret->url)
|
||||
return NULL;
|
||||
|
18
revision.c
18
revision.c
@ -994,16 +994,6 @@ static void add_message_grep(struct rev_info *revs, const char *pattern)
|
||||
add_grep(revs, pattern, GREP_PATTERN_BODY);
|
||||
}
|
||||
|
||||
static void add_ignore_packed(struct rev_info *revs, const char *name)
|
||||
{
|
||||
int num = ++revs->num_ignore_packed;
|
||||
|
||||
revs->ignore_packed = xrealloc(revs->ignore_packed,
|
||||
sizeof(const char *) * (num + 1));
|
||||
revs->ignore_packed[num-1] = name;
|
||||
revs->ignore_packed[num] = NULL;
|
||||
}
|
||||
|
||||
static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
|
||||
int *unkc, const char **unkv)
|
||||
{
|
||||
@ -1116,12 +1106,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
||||
revs->edge_hint = 1;
|
||||
} else if (!strcmp(arg, "--unpacked")) {
|
||||
revs->unpacked = 1;
|
||||
free(revs->ignore_packed);
|
||||
revs->ignore_packed = NULL;
|
||||
revs->num_ignore_packed = 0;
|
||||
} else if (!prefixcmp(arg, "--unpacked=")) {
|
||||
revs->unpacked = 1;
|
||||
add_ignore_packed(revs, arg+11);
|
||||
die("--unpacked=<packfile> no longer supported.");
|
||||
} else if (!strcmp(arg, "-r")) {
|
||||
revs->diff = 1;
|
||||
DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
|
||||
@ -1685,7 +1671,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
{
|
||||
if (commit->object.flags & SHOWN)
|
||||
return commit_ignore;
|
||||
if (revs->unpacked && has_sha1_pack(commit->object.sha1, revs->ignore_packed))
|
||||
if (revs->unpacked && has_sha1_pack(commit->object.sha1))
|
||||
return commit_ignore;
|
||||
if (revs->show_all)
|
||||
return commit_show;
|
||||
|
@ -49,7 +49,7 @@ struct rev_info {
|
||||
blob_objects:1,
|
||||
edge_hint:1,
|
||||
limited:1,
|
||||
unpacked:1, /* see also ignore_packed below */
|
||||
unpacked:1,
|
||||
boundary:2,
|
||||
left_right:1,
|
||||
rewrite_parents:1,
|
||||
@ -80,9 +80,6 @@ struct rev_info {
|
||||
missing_newline:1;
|
||||
enum date_mode date_mode;
|
||||
|
||||
const char **ignore_packed; /* pretend objects in these are unpacked */
|
||||
int num_ignore_packed;
|
||||
|
||||
unsigned int abbrev;
|
||||
enum cmit_fmt commit_format;
|
||||
struct log_info *loginfo;
|
||||
|
@ -10,7 +10,7 @@ enum {
|
||||
ERR_RUN_COMMAND_WAITPID_SIGNAL,
|
||||
ERR_RUN_COMMAND_WAITPID_NOEXIT,
|
||||
};
|
||||
#define IS_RUN_COMMAND_ERR(x) ((x) <= -ERR_RUN_COMMAND_FORK)
|
||||
#define IS_RUN_COMMAND_ERR(x) (-(x) >= ERR_RUN_COMMAND_FORK)
|
||||
|
||||
struct child_process {
|
||||
const char **argv;
|
||||
|
4
setup.c
4
setup.c
@ -434,7 +434,7 @@ int git_config_perm(const char *var, const char *value)
|
||||
|
||||
/*
|
||||
* Treat values 0, 1 and 2 as compatibility cases, otherwise it is
|
||||
* a chmod value.
|
||||
* a chmod value to restrict to.
|
||||
*/
|
||||
switch (i) {
|
||||
case PERM_UMASK: /* 0 */
|
||||
@ -456,7 +456,7 @@ int git_config_perm(const char *var, const char *value)
|
||||
* Mask filemode value. Others can not get write permission.
|
||||
* x flags for directories are handled separately.
|
||||
*/
|
||||
return i & 0666;
|
||||
return -(i & 0666);
|
||||
}
|
||||
|
||||
int check_repository_format_version(const char *var, const char *value, void *cb)
|
||||
|
57
sha1_file.c
57
sha1_file.c
@ -1919,25 +1919,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int matches_pack_name(struct packed_git *p, const char *name)
|
||||
{
|
||||
const char *last_c, *c;
|
||||
|
||||
if (!strcmp(p->pack_name, name))
|
||||
return 1;
|
||||
|
||||
for (c = p->pack_name, last_c = c; *c;)
|
||||
if (*c == '/')
|
||||
last_c = ++c;
|
||||
else
|
||||
++c;
|
||||
if (!strcmp(last_c, name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
|
||||
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
|
||||
{
|
||||
static struct packed_git *last_found = (void *)1;
|
||||
struct packed_git *p;
|
||||
@ -1949,15 +1931,6 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons
|
||||
p = (last_found == (void *)1) ? packed_git : last_found;
|
||||
|
||||
do {
|
||||
if (ignore_packed) {
|
||||
const char **ig;
|
||||
for (ig = ignore_packed; *ig; ig++)
|
||||
if (matches_pack_name(p, *ig))
|
||||
break;
|
||||
if (*ig)
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (p->num_bad_objects) {
|
||||
unsigned i;
|
||||
for (i = 0; i < p->num_bad_objects; i++)
|
||||
@ -2038,7 +2011,7 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
|
||||
struct pack_entry e;
|
||||
int status;
|
||||
|
||||
if (!find_pack_entry(sha1, &e, NULL)) {
|
||||
if (!find_pack_entry(sha1, &e)) {
|
||||
/* Most likely it's a loose object. */
|
||||
status = sha1_loose_object_info(sha1, sizep);
|
||||
if (status >= 0)
|
||||
@ -2046,7 +2019,7 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
|
||||
|
||||
/* Not a loose object; someone else may have just packed it. */
|
||||
reprepare_packed_git();
|
||||
if (!find_pack_entry(sha1, &e, NULL))
|
||||
if (!find_pack_entry(sha1, &e))
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -2065,7 +2038,7 @@ static void *read_packed_sha1(const unsigned char *sha1,
|
||||
struct pack_entry e;
|
||||
void *data;
|
||||
|
||||
if (!find_pack_entry(sha1, &e, NULL))
|
||||
if (!find_pack_entry(sha1, &e))
|
||||
return NULL;
|
||||
data = cache_or_unpack_entry(e.p, e.offset, size, type, 1);
|
||||
if (!data) {
|
||||
@ -2243,11 +2216,15 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the just written object into its final resting place
|
||||
* Move the just written object into its final resting place.
|
||||
* NEEDSWORK: this should be renamed to finalize_temp_file() as
|
||||
* "moving" is only a part of what it does, when no patch between
|
||||
* master to pu changes the call sites of this function.
|
||||
*/
|
||||
int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (link(tmpfile, filename))
|
||||
ret = errno;
|
||||
|
||||
@ -2259,12 +2236,12 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
*
|
||||
* The same holds for FAT formatted media.
|
||||
*
|
||||
* When this succeeds, we just return 0. We have nothing
|
||||
* When this succeeds, we just return. We have nothing
|
||||
* left to unlink.
|
||||
*/
|
||||
if (ret && ret != EEXIST) {
|
||||
if (!rename(tmpfile, filename))
|
||||
return 0;
|
||||
goto out;
|
||||
ret = errno;
|
||||
}
|
||||
unlink(tmpfile);
|
||||
@ -2275,6 +2252,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
/* FIXME!!! Collision check here ? */
|
||||
}
|
||||
|
||||
out:
|
||||
if (set_shared_perm(filename, (S_IFREG|0444)))
|
||||
return error("unable to set permission to '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2299,9 +2279,8 @@ static void close_sha1_file(int fd)
|
||||
{
|
||||
if (fsync_object_files)
|
||||
fsync_or_die(fd, "sha1 file");
|
||||
fchmod(fd, 0444);
|
||||
if (close(fd) != 0)
|
||||
die("unable to write sha1 file");
|
||||
die("error when closing sha1 file (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
/* Size of directory component, including the ending '/' */
|
||||
@ -2464,17 +2443,17 @@ int has_pack_file(const unsigned char *sha1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int has_sha1_pack(const unsigned char *sha1, const char **ignore_packed)
|
||||
int has_sha1_pack(const unsigned char *sha1)
|
||||
{
|
||||
struct pack_entry e;
|
||||
return find_pack_entry(sha1, &e, ignore_packed);
|
||||
return find_pack_entry(sha1, &e);
|
||||
}
|
||||
|
||||
int has_sha1_file(const unsigned char *sha1)
|
||||
{
|
||||
struct pack_entry e;
|
||||
|
||||
if (find_pack_entry(sha1, &e, NULL))
|
||||
if (find_pack_entry(sha1, &e))
|
||||
return 1;
|
||||
return has_loose_object(sha1);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ pre-clean:
|
||||
$(RM) -r test-results
|
||||
|
||||
clean:
|
||||
$(RM) -r 'trash directory' test-results
|
||||
$(RM) -r 'trash directory'.* test-results
|
||||
|
||||
aggregate-results-and-cleanup: $(T)
|
||||
$(MAKE) aggregate-results
|
||||
|
31
t/t1008-read-tree-overlay.sh
Executable file
31
t/t1008-read-tree-overlay.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test multi-tree read-tree without merging'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
echo one >a &&
|
||||
git add a &&
|
||||
git commit -m initial &&
|
||||
git tag initial &&
|
||||
echo two >b &&
|
||||
git add b &&
|
||||
git commit -m second &&
|
||||
git checkout -b side initial &&
|
||||
echo three >a &&
|
||||
mkdir b &&
|
||||
echo four >b/c &&
|
||||
git add b/c &&
|
||||
git commit -m third
|
||||
'
|
||||
|
||||
test_expect_success 'multi-read' '
|
||||
git read-tree initial master side &&
|
||||
(echo a; echo b/c) >expect &&
|
||||
git ls-files >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -126,4 +126,41 @@ test_expect_success 'git reflog expire honors core.sharedRepository' '
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success 'forced modes' '
|
||||
mkdir -p templates/hooks &&
|
||||
echo update-server-info >templates/hooks/post-update &&
|
||||
chmod +x templates/hooks/post-update &&
|
||||
echo : >random-file &&
|
||||
mkdir new &&
|
||||
(
|
||||
cd new &&
|
||||
umask 002 &&
|
||||
git init --shared=0660 --template=../templates &&
|
||||
>frotz &&
|
||||
git add frotz &&
|
||||
git commit -a -m initial &&
|
||||
git repack
|
||||
) &&
|
||||
find new/.git -print |
|
||||
xargs ls -ld >actual &&
|
||||
|
||||
# Everything must be unaccessible to others
|
||||
test -z "$(sed -n -e "/^.......---/d" actual)" &&
|
||||
|
||||
# All directories must have either 2770 or 770
|
||||
test -z "$(sed -n -e "/^drwxrw[sx]---/d" -e "/^d/p" actual)" &&
|
||||
|
||||
# post-update hook must be 0770
|
||||
test -z "$(sed -n -e "/post-update/{
|
||||
/^-rwxrwx---/d
|
||||
p
|
||||
}" actual)" &&
|
||||
|
||||
# All files inside objects must be 0440
|
||||
test -z "$(sed -n -e "/objects\//{
|
||||
/^d/d
|
||||
/^-r--r-----/d
|
||||
}" actual)"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -195,7 +195,7 @@ test_expect_success 'test deleting branch deletes branch config' \
|
||||
test_expect_success 'test deleting branch without config' \
|
||||
'git branch my7 s &&
|
||||
sha1=$(git rev-parse my7 | cut -c 1-7) &&
|
||||
test "$(git branch -d my7 2>&1)" = "Deleted branch my7 ($sha1)."'
|
||||
test "$(git branch -d my7 2>&1)" = "Deleted branch my7 (was $sha1)."'
|
||||
|
||||
test_expect_success 'test --track without .fetch entries' \
|
||||
'git branch --track my8 &&
|
||||
|
@ -136,4 +136,28 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
|
||||
GIT_EXTERNAL_DIFF=echo git diff
|
||||
'
|
||||
|
||||
echo "#!$SHELL_PATH" >fake-diff.sh
|
||||
cat >> fake-diff.sh <<\EOF
|
||||
cat $2 >> crlfed.txt
|
||||
EOF
|
||||
chmod a+x fake-diff.sh
|
||||
|
||||
keep_only_cr () {
|
||||
tr -dc '\015'
|
||||
}
|
||||
|
||||
test_expect_success 'external diff with autocrlf = true' '
|
||||
git config core.autocrlf true &&
|
||||
GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
|
||||
test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
|
||||
'
|
||||
|
||||
test_expect_success 'diff --cached' '
|
||||
git add file &&
|
||||
git update-index --assume-unchanged file &&
|
||||
echo second >file &&
|
||||
git diff --cached >actual &&
|
||||
test_cmp ../t4020/diff.NUL actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -191,38 +191,39 @@ test_expect_success 'bundle should be able to create a full history' '
|
||||
|
||||
'
|
||||
|
||||
test "$TEST_RSYNC" && {
|
||||
! rsync --help > /dev/null 2> /dev/null &&
|
||||
say 'Skipping rsync tests because rsync was not found' || {
|
||||
test_expect_success 'fetch via rsync' '
|
||||
git pack-refs &&
|
||||
mkdir rsynced &&
|
||||
cd rsynced &&
|
||||
git init &&
|
||||
git fetch rsync://127.0.0.1$(pwd)/../.git master:refs/heads/master &&
|
||||
git gc --prune &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full
|
||||
(cd rsynced &&
|
||||
git init --bare &&
|
||||
git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
|
||||
git gc --prune &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full)
|
||||
'
|
||||
|
||||
test_expect_success 'push via rsync' '
|
||||
mkdir ../rsynced2 &&
|
||||
(cd ../rsynced2 &&
|
||||
mkdir rsynced2 &&
|
||||
(cd rsynced2 &&
|
||||
git init) &&
|
||||
git push rsync://127.0.0.1$(pwd)/../rsynced2/.git master &&
|
||||
cd ../rsynced2 &&
|
||||
git gc --prune &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full
|
||||
(cd rsynced &&
|
||||
git push "rsync:$(pwd)/../rsynced2/.git" master) &&
|
||||
(cd rsynced2 &&
|
||||
git gc --prune &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full)
|
||||
'
|
||||
|
||||
test_expect_success 'push via rsync' '
|
||||
cd .. &&
|
||||
mkdir rsynced3 &&
|
||||
(cd rsynced3 &&
|
||||
git init) &&
|
||||
git push --all rsync://127.0.0.1$(pwd)/rsynced3/.git &&
|
||||
cd rsynced3 &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full
|
||||
git push --all "rsync:$(pwd)/rsynced3/.git" &&
|
||||
(cd rsynced3 &&
|
||||
test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
|
||||
git fsck --full)
|
||||
'
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ test_expect_success 'checkout to detach HEAD' '
|
||||
git checkout -f renamer && git clean -f &&
|
||||
git checkout renamer^ 2>messages &&
|
||||
(cat >messages.expect <<EOF
|
||||
Note: moving to "renamer^" which isn'"'"'t a local branch
|
||||
Note: moving to '\''renamer^'\'' which isn'\''t a local branch
|
||||
If you want to create a new branch from this checkout, you may do so
|
||||
(now or later) by using -b with the checkout command again. Example:
|
||||
git checkout -b <new_branch_name>
|
||||
|
@ -47,6 +47,55 @@ test_expect_success 'Prepare submodule testing' '
|
||||
GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git
|
||||
'
|
||||
|
||||
test_expect_success 'Prepare submodule add testing' '
|
||||
submodurl=$(pwd)
|
||||
(
|
||||
mkdir addtest &&
|
||||
cd addtest &&
|
||||
git init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add' '
|
||||
(
|
||||
cd addtest &&
|
||||
git submodule add "$submodurl" submod &&
|
||||
git submodule init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add with ./ in path' '
|
||||
(
|
||||
cd addtest &&
|
||||
git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
|
||||
git submodule init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add with // in path' '
|
||||
(
|
||||
cd addtest &&
|
||||
git submodule add "$submodurl" slashslashsubmod///frotz// &&
|
||||
git submodule init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add with /.. in path' '
|
||||
(
|
||||
cd addtest &&
|
||||
git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
|
||||
git submodule init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add with ./, /.. and // in path' '
|
||||
(
|
||||
cd addtest &&
|
||||
git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
|
||||
git submodule init
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'status should fail for unmapped paths' '
|
||||
if git submodule status
|
||||
then
|
||||
|
@ -88,5 +88,66 @@ test_expect_failure 'packed obs in alt ODB are repacked when local repo has pack
|
||||
done
|
||||
'
|
||||
|
||||
test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
|
||||
# swap the .keep so the commit object is in the pack with .keep
|
||||
for p in alt_objects/pack/*.pack
|
||||
do
|
||||
base_name=$(basename $p .pack)
|
||||
if test -f alt_objects/pack/$base_name.keep
|
||||
then
|
||||
rm alt_objects/pack/$base_name.keep
|
||||
else
|
||||
touch alt_objects/pack/$base_name.keep
|
||||
fi
|
||||
done
|
||||
git repack -a -d &&
|
||||
myidx=$(ls -1 .git/objects/pack/*.idx) &&
|
||||
test -f "$myidx" &&
|
||||
for p in alt_objects/pack/*.idx; do
|
||||
git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
|
||||
done | while read sha1 rest; do
|
||||
if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
|
||||
echo "Missing object in local pack: $sha1"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
'
|
||||
|
||||
test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
|
||||
rm -f alt_objects/pack/*.keep &&
|
||||
mv .git/objects/pack/* alt_objects/pack/ &&
|
||||
csha1=$(git rev-parse HEAD^{commit}) &&
|
||||
git reset --hard HEAD^ &&
|
||||
sleep 1 &&
|
||||
git reflog expire --expire=now --expire-unreachable=now --all &&
|
||||
# The pack-objects call on the next line is equivalent to
|
||||
# git repack -A -d without the call to prune-packed
|
||||
git pack-objects --honor-pack-keep --non-empty --all --reflog \
|
||||
--unpack-unreachable </dev/null pack &&
|
||||
rm -f .git/objects/pack/* &&
|
||||
mv pack-* .git/objects/pack/ &&
|
||||
test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
|
||||
egrep "^$csha1 " | sort | uniq | wc -l) &&
|
||||
echo > .git/objects/info/alternates &&
|
||||
test_must_fail git show $csha1
|
||||
'
|
||||
|
||||
test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
|
||||
echo `pwd`/alt_objects > .git/objects/info/alternates &&
|
||||
echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
|
||||
rm -f .git/objects/pack/* &&
|
||||
mv pack-* .git/objects/pack/ &&
|
||||
# The pack-objects call on the next line is equivalent to
|
||||
# git repack -A -d without the call to prune-packed
|
||||
git pack-objects --honor-pack-keep --non-empty --all --reflog \
|
||||
--unpack-unreachable </dev/null pack &&
|
||||
rm -f .git/objects/pack/* &&
|
||||
mv pack-* .git/objects/pack/ &&
|
||||
test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
|
||||
egrep "^$csha1 " | sort | uniq | wc -l) &&
|
||||
echo > .git/objects/info/alternates &&
|
||||
test_must_fail git show $csha1
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
|
@ -455,4 +455,15 @@ test_expect_success 'feed two files' '
|
||||
test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
|
||||
'
|
||||
|
||||
test_expect_success 'in-reply-to but no threading' '
|
||||
git send-email \
|
||||
--dry-run \
|
||||
--from="Example <nobody@example.com>" \
|
||||
--to=nobody@example.com \
|
||||
--in-reply-to="<in-reply-id@example.com>" \
|
||||
--no-thread \
|
||||
$patches |
|
||||
grep "In-Reply-To: <in-reply-id@example.com>"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -466,14 +466,6 @@ test_done () {
|
||||
fi
|
||||
case "$test_failure" in
|
||||
0)
|
||||
# We could:
|
||||
# cd .. && rm -fr 'trash directory'
|
||||
# but that means we forbid any tests that use their own
|
||||
# subdirectory from calling test_done without coming back
|
||||
# to where they started from.
|
||||
# The Makefile provided will clean this test area so
|
||||
# we will leave things as they are.
|
||||
|
||||
say_color pass "passed all $msg"
|
||||
|
||||
test -d "$remove_trash" &&
|
||||
|
23
transport.c
23
transport.c
@ -138,6 +138,11 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *rsync_url(const char *url)
|
||||
{
|
||||
return prefixcmp(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
|
||||
}
|
||||
|
||||
static struct ref *get_refs_via_rsync(struct transport *transport)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
|
||||
@ -153,7 +158,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport)
|
||||
die ("Could not make temporary directory");
|
||||
temp_dir_len = temp_dir.len;
|
||||
|
||||
strbuf_addstr(&buf, transport->url);
|
||||
strbuf_addstr(&buf, rsync_url(transport->url));
|
||||
strbuf_addstr(&buf, "/refs");
|
||||
|
||||
memset(&rsync, 0, sizeof(rsync));
|
||||
@ -169,7 +174,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport)
|
||||
die ("Could not run rsync to get refs");
|
||||
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addstr(&buf, transport->url);
|
||||
strbuf_addstr(&buf, rsync_url(transport->url));
|
||||
strbuf_addstr(&buf, "/packed-refs");
|
||||
|
||||
args[2] = buf.buf;
|
||||
@ -206,7 +211,7 @@ static int fetch_objs_via_rsync(struct transport *transport,
|
||||
const char *args[8];
|
||||
int result;
|
||||
|
||||
strbuf_addstr(&buf, transport->url);
|
||||
strbuf_addstr(&buf, rsync_url(transport->url));
|
||||
strbuf_addstr(&buf, "/objects/");
|
||||
|
||||
memset(&rsync, 0, sizeof(rsync));
|
||||
@ -285,7 +290,7 @@ static int rsync_transport_push(struct transport *transport,
|
||||
|
||||
/* first push the objects */
|
||||
|
||||
strbuf_addstr(&buf, transport->url);
|
||||
strbuf_addstr(&buf, rsync_url(transport->url));
|
||||
strbuf_addch(&buf, '/');
|
||||
|
||||
memset(&rsync, 0, sizeof(rsync));
|
||||
@ -306,7 +311,8 @@ static int rsync_transport_push(struct transport *transport,
|
||||
args[i++] = NULL;
|
||||
|
||||
if (run_command(&rsync))
|
||||
return error("Could not push objects to %s", transport->url);
|
||||
return error("Could not push objects to %s",
|
||||
rsync_url(transport->url));
|
||||
|
||||
/* copy the refs to the temporary directory; they could be packed. */
|
||||
|
||||
@ -327,10 +333,11 @@ static int rsync_transport_push(struct transport *transport,
|
||||
if (!(flags & TRANSPORT_PUSH_FORCE))
|
||||
args[i++] = "--ignore-existing";
|
||||
args[i++] = temp_dir.buf;
|
||||
args[i++] = transport->url;
|
||||
args[i++] = rsync_url(transport->url);
|
||||
args[i++] = NULL;
|
||||
if (run_command(&rsync))
|
||||
result = error("Could not push to %s", transport->url);
|
||||
result = error("Could not push to %s",
|
||||
rsync_url(transport->url));
|
||||
|
||||
if (remove_dir_recursively(&temp_dir, 0))
|
||||
warning ("Could not remove temporary directory %s.",
|
||||
@ -723,7 +730,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
||||
ret->remote = remote;
|
||||
ret->url = url;
|
||||
|
||||
if (!prefixcmp(url, "rsync://")) {
|
||||
if (!prefixcmp(url, "rsync:")) {
|
||||
ret->get_refs_list = get_refs_via_rsync;
|
||||
ret->fetch = fetch_objs_via_rsync;
|
||||
ret->push = rsync_transport_push;
|
||||
|
@ -49,7 +49,7 @@ static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
|
||||
memcpy(new, ce, size);
|
||||
new->next = NULL;
|
||||
new->ce_flags = (new->ce_flags & ~clear) | set;
|
||||
add_index_entry(&o->result, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|ADD_CACHE_SKIP_DFCHECK);
|
||||
add_index_entry(&o->result, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
|
||||
}
|
||||
|
||||
/* Unlink the last component and attempt to remove leading
|
||||
@ -286,9 +286,9 @@ static int unpack_nondirectories(int n, unsigned long mask,
|
||||
if (o->merge)
|
||||
return call_unpack_fn(src, o);
|
||||
|
||||
n += o->merge;
|
||||
for (i = 0; i < n; i++)
|
||||
add_entry(o, src[i], 0, 0);
|
||||
if (src[i] && src[i] != o->df_conflict_entry)
|
||||
add_entry(o, src[i], 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user