1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-17 22:44:49 +01:00

Merge branch 'fixes'

This commit is contained in:
Junio C Hamano 2005-10-05 15:33:58 -07:00
commit 952f87a6ca
27 changed files with 241 additions and 148 deletions

View file

@ -24,7 +24,7 @@ The good news is that most people don't do that, and in fact most sane
people think it's a bug in CVS that makes it tag (and check in changes) people think it's a bug in CVS that makes it tag (and check in changes)
one file at a time. So most projects you'll ever see will use CVS one file at a time. So most projects you'll ever see will use CVS
'as if' it was sane. In which case you'll find it very easy indeed to 'as if' it was sane. In which case you'll find it very easy indeed to
move over to Git. move over to git.
First off: this is not a git tutorial. See First off: this is not a git tutorial. See
link:tutorial.html[Documentation/tutorial.txt] for how git link:tutorial.html[Documentation/tutorial.txt] for how git
@ -229,7 +229,7 @@ does rename or copy would not show in the output, and if the
"o-file.c", it would find the commit that changed the statement "o-file.c", it would find the commit that changed the statement
when it was in "o-file.c". when it was in "o-file.c".
NOTE: The current versions of "git-diff-tree -C" is not eager NOTE: The current version of "git-diff-tree -C" is not eager
enough to find copies, and it will miss the fact that a-file.c enough to find copies, and it will miss the fact that a-file.c
was created by copying o-file.c unless o-file.c was somehow was created by copying o-file.c unless o-file.c was somehow
changed in the same commit. changed in the same commit.

View file

@ -1,8 +1,8 @@
The output format from "git-diff-index", "git-diff-tree" and The output format from "git-diff-index", "git-diff-tree" and
"git-diff-files" are very similar. "git-diff-files" are very similar.
These commands all compare two sets of things; what are These commands all compare two sets of things; what is
compared are different: compared differs:
git-diff-index <tree-ish>:: git-diff-index <tree-ish>::
compares the <tree-ish> and the files on the filesystem. compares the <tree-ish> and the files on the filesystem.
@ -46,7 +46,7 @@ That is, from the left to the right:
. path for "dst"; only exists for C or R. . path for "dst"; only exists for C or R.
. an LF or a NUL when '-z' option is used, to terminate the record. . an LF or a NUL when '-z' option is used, to terminate the record.
<sha1> is shown as all 0's if new is a file on the filesystem <sha1> is shown as all 0's if a file is new on the filesystem
and it is out of sync with the cache. and it is out of sync with the cache.
Example: Example:
@ -91,7 +91,7 @@ For a path that is added, removed, or modified,
where: where:
<old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the <old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|ne>, contents of <old|new>,
<old|new>-hex:: are the 40-hexdigit SHA1 hashes, <old|new>-hex:: are the 40-hexdigit SHA1 hashes,
<old|new>-mode:: are the octal representation of the file modes. <old|new>-mode:: are the octal representation of the file modes.
@ -121,12 +121,11 @@ The `a/` and `b/` filenames are the same unless rename/copy is
involved. Especially, even for a creation or a deletion, involved. Especially, even for a creation or a deletion,
`/dev/null` is _not_ used in place of `a/` or `b/` filenames. `/dev/null` is _not_ used in place of `a/` or `b/` filenames.
+ +
When rename/copy is involved, `file1` and `file2` shows the When rename/copy is involved, `file1` and `file2` show the
name of the source file of the rename/copy and the name of name of the source file of the rename/copy and the name of
the file that rename/copy produces, respectively. the file that rename/copy produces, respectively.
2. It is followed by extended header lines that are one or 2. It is followed by one or more extended header lines:
more of:
old mode <mode> old mode <mode>
new mode <mode> new mode <mode>

View file

@ -5,9 +5,8 @@
Synonym for "-p". Synonym for "-p".
-r:: -r::
Look recursively in subdirectories; this flag does not Look recursively in subdirectories; only used by "git-diff-tree";
mean anything to commands other than "git-diff-tree"; other diff commands always work recursively.
other diff commands always look at all the subdirectories.
-z:: -z::
\0 line termination on output \0 line termination on output
@ -28,26 +27,26 @@
Detect copies as well as renames. Detect copies as well as renames.
--find-copies-harder:: --find-copies-harder::
By default, -C option finds copies only if the original For performance reasons, by default, -C option finds copies only
file of the copy was modified in the same changeset for if the original file of the copy was modified in the same
performance reasons. This flag makes the command changeset. This flag makes the command
inspect unmodified files as candidates for the source of inspect unmodified files as candidates for the source of
copy. This is a very expensive operation for large copy. This is a very expensive operation for large
projects, so use it with caution. projects, so use it with caution.
-l<num>:: -l<num>::
-M and -C options require O(n^2) processing time where n -M and -C options require O(n^2) processing time where n
in the number of potential rename/copy targets. This is the number of potential rename/copy targets. This
option prevents rename/copy detection from running if option prevents rename/copy detection from running if
the number of rename/copy targets exceed the specified the number of rename/copy targets exceeds the specified
number. number.
-S<string>:: -S<string>::
Look for differences that contains the change in <string>. Look for differences that contain the change in <string>.
--pickaxe-all:: --pickaxe-all::
When -S finds a change, show all the changes in that When -S finds a change, show all the changes in that
changeset, not just the files that contains the change changeset, not just the files that contain the change
in <string>. in <string>.
-O<orderfile>:: -O<orderfile>::

View file

@ -177,7 +177,7 @@ diffcore-merge-broken
--------------------- ---------------------
This transformation is used to merge filepairs broken by This transformation is used to merge filepairs broken by
diffcore-break, and were not transformed into rename/copy by diffcore-break, and not transformed into rename/copy by
diffcore-rename, back into a single modification. This always diffcore-rename, back into a single modification. This always
runs when diffcore-break is used. runs when diffcore-break is used.
@ -206,10 +206,10 @@ like these:
* -B/60 (the same as above, since diffcore-break defaults to 50%). * -B/60 (the same as above, since diffcore-break defaults to 50%).
Note that earlier implementation left a broken pair as a separate Note that earlier implementation left a broken pair as a separate
creation and deletion patches. This was unnecessary hack and creation and deletion patches. This was an unnecessary hack and
the latest implementation always merges all the broken pairs the latest implementation always merges all the broken pairs
back into modifications, but the resulting patch output is back into modifications, but the resulting patch output is
formatted differently to still let the reviewing easier for such formatted differently for easier review in case of such
a complete rewrite by showing the entire contents of old version a complete rewrite by showing the entire contents of old version
prefixed with '-', followed by the entire contents of new prefixed with '-', followed by the entire contents of new
version prefixed with '+'. version prefixed with '+'.

View file

@ -11,7 +11,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
A simple wrapper to git-update-index to add files to the cache for people used A simple wrapper for git-update-index to add files to the cache for people used
to do "cvs add". to do "cvs add".
OPTIONS OPTIONS

View file

@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
Reads supplied diff output and applies it on a GIT index file Reads supplied diff output and applies it on a git index file
and a work tree. and a work tree.
OPTIONS OPTIONS

View file

@ -22,7 +22,7 @@ OPTIONS
-q:: -q::
Apply patches interactively. The user will be given Apply patches interactively. The user will be given
opportunity to edit the log message and the patch before opportunity to edit the log message and the patch before
attempting to apply patch in each e-mail message. attempting to apply it.
-k:: -k::
Usually the program 'cleans up' the Subject: header line Usually the program 'cleans up' the Subject: header line

View file

@ -20,20 +20,23 @@ it will just import it as a regular commit. If it can find it, it will mark it
as a merge whenever possible (see discussion below). as a merge whenever possible (see discussion below).
The script expects you to provide the key roots where it can start the import The script expects you to provide the key roots where it can start the import
from an 'initial import' or 'tag' type of Arch commit. It will follow and import from an 'initial import' or 'tag' type of Arch commit. It will follow and
new branches within the provided roots. import new branches within the provided roots.
It expects to be dealing with one project only. If it sees It expects to be dealing with one project only. If it sees
branches that have different roots, it will refuse to run. In that case, edit your branches that have different roots, it will refuse to run. In that case,
<archive/branch> parameters to define clearly the scope of the import. edit your <archive/branch> parameters to define clearly the scope of the
import.
`git-archimport` uses `tla` extensively in the background to access the Arch repository. `git-archimport` uses `tla` extensively in the background to access the
Arch repository.
Make sure you have a recent version of `tla` available in the path. `tla` must Make sure you have a recent version of `tla` available in the path. `tla` must
know about the repositories you pass to `git-archimport`. know about the repositories you pass to `git-archimport`.
For the initial import `git-archimport` expects to find itself in an empty For the initial import `git-archimport` expects to find itself in an empty
directory. To follow the development of a project that uses Arch, rerun directory. To follow the development of a project that uses Arch, rerun
`git-archimport` with the same parameters as the initial import to perform incremental imports. `git-archimport` with the same parameters as the initial import to perform
incremental imports.
MERGES MERGES
------ ------

View file

@ -76,7 +76,7 @@ During the bisection process, you can say
to see the currently remaining suspects in `gitk`. to see the currently remaining suspects in `gitk`.
The good/bad you told the command is logged, and `git bisect The good/bad input is logged, and `git bisect
log` shows what you have done so far. You can truncate its log` shows what you have done so far. You can truncate its
output somewhere and save it in a file, and run output somewhere and save it in a file, and run

View file

@ -23,7 +23,7 @@ OPTIONS
The name of the branch to create. The name of the branch to create.
start-point:: start-point::
Where to make the branch; defaults to HEAD. Where to create the branch; defaults to HEAD.
Author Author
------ ------

View file

@ -32,7 +32,7 @@ OPTIONS
<type>:: <type>::
Typically this matches the real type of <object> but asking Typically this matches the real type of <object> but asking
for a type that can trivially dereferenced from the given for a type that can trivially be dereferenced from the given
<object> is also permitted. An example is to ask for a <object> is also permitted. An example is to ask for a
"tree" with <object> being a commit object that contains it, "tree" with <object> being a commit object that contains it,
or to ask for a "blob" with <object> being a tag object that or to ask for a "blob" with <object> being a tag object that

View file

@ -22,7 +22,7 @@ OPTIONS
Commit to cherry-pick. Commit to cherry-pick.
-r:: -r::
Usuall the command appends which commit was Usually the command appends which commit was
cherry-picked after the original commit message when cherry-picked after the original commit message when
making a commit. This option, '--replay', causes it to making a commit. This option, '--replay', causes it to
use the original commit message intact. This is useful use the original commit message intact. This is useful

View file

@ -26,8 +26,8 @@ OPTIONS
--exec=<git-upload-pack>:: --exec=<git-upload-pack>::
Use this to specify the path to 'git-upload-pack' on the Use this to specify the path to 'git-upload-pack' on the
remote side, if is not found on your $PATH. remote side, if it is not found on your $PATH.
Installations of sshd ignores the user's environment Installations of sshd ignore the user's environment
setup scripts for login shells (e.g. .bash_profile) and setup scripts for login shells (e.g. .bash_profile) and
your privately installed GIT may not be found on the system your privately installed GIT may not be found on the system
default $PATH. Another workaround suggested is to set default $PATH. Another workaround suggested is to set

View file

@ -36,7 +36,7 @@ OPTIONS
An existing tree object An existing tree object
-p <parent commit>:: -p <parent commit>::
Each '-p' indicates a the id of a parent commit object. Each '-p' indicates the id of a parent commit object.
Commit Information Commit Information

View file

@ -0,0 +1,52 @@
git-symbolic-ref(1)
===================
NAME
----
git-symbolic-ref - read and modify symbolic refs
SYNOPSIS
--------
'git-symbolic-ref' <name> [<ref>]
DESCRIPTION
-----------
Given one argument, reads which branch head the given symbolic
ref refers to and outputs its path, relative to the `.git/`
directory. Typically you would give `HEAD` as the <name>
argument to see on which branch your working tree is on.
Give two arguments, create or update a symbolic ref <name> to
point at the given branch <ref>.
Traditionally, `.git/HEAD` is a symlink pointing at
`refs/heads/master`. When we want to switch to another branch,
we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we want
to find out which branch we are on, we did `readlink .git/HEAD`.
This was fine, and internally that is what still happens by
default, but on platforms that does not have working symlinks,
or that does not have the `readlink(1)` command, this was a bit
cumbersome. On some platforms, `ln -sf` does not even work as
advertised (horrors).
A symbolic ref can be a regular file that stores a string that
begins with `ref: refs/`. For example, your `.git/HEAD` *can*
be a regular file whose contents is `ref: refs/heads/master`.
This can be used on a filesystem that does not support symbolic
links. Instead of doing `readlink .git/HEAD`, `git-symbolic-ref
HEAD` can be used to find out which branch we are on. To point
the HEAD to `newbranch`, instead of `ln -sf refs/heads/newbranch
.git/HEAD`, `git-symbolic-ref HEAD refs/heads/newbranch` can be
used.
Currently, .git/HEAD uses a regular file symbolic ref on Cygwin,
and everywhere else it is implemented as a symlink. This can be
changed at compilation time.
Author
------
Written by Junio C Hamano <junkio@cox.net>
GIT
---
Part of the gitlink:git[7] suite

View file

@ -0,0 +1,58 @@
git-update-ref(1)
=================
NAME
----
git-update-ref - update the object name stored in a ref safely
SYNOPSIS
--------
`git-update-ref` <ref> <newvalue> [<oldvalue>]
DESCRIPTION
-----------
Given two arguments, stores the <newvalue> in the <ref>, possibly
dereferencing the symbolic refs. E.g. `git-update-ref HEAD
<newvalue>` updates the current branch head to the new object.
Given three arguments, stores the <newvalue> in the <ref>,
possibly dereferencing the symbolic refs, after verifying that
the current value of the <ref> matches <oldvalue>.
E.g. `git-update-ref refs/heads/master <newvalue> <oldvalue>`
updates the master branch head to <newvalue> only if its current
value is <oldvalue>.
It also allows a "ref" file to be a symbolic pointer to another
ref file by starting with the four-byte header sequence of
"ref:".
More importantly, it allows the update of a ref file to follow
these symbolic pointers, whether they are symlinks or these
"regular file symbolic refs". It follows *real* symlinks only
if they start with "refs/": otherwise it will just try to read
them and update them as a regular file (i.e. it will allow the
filesystem to follow them, but will overwrite such a symlink to
somewhere else with a regular filename).
In general, using
git-update-ref HEAD "$head"
should be a _lot_ safer than doing
echo "$head" > "$GIT_DIR/HEAD"
both from a symlink following standpoint *and* an error checking
standpoint. The "refs/" rule for symlinks means that symlinks
that point to "outside" the tree are safe: they'll be followed
for reading but not for writing (so we'll never write through a
ref symlink to some other tree, if you have copied a whole
archive by creating a symlink tree).
Author
------
Written by Linus Torvalds <torvalds@osdl.org>.
GIT
---
Part of the gitlink:git[7] suite

View file

@ -51,6 +51,7 @@ static void write_refs(struct ref *ref)
struct ref *head = NULL, *head_ptr, *master_ref; struct ref *head = NULL, *head_ptr, *master_ref;
char *head_path; char *head_path;
/* Upload-pack must report HEAD first */
if (!strcmp(ref->name, "HEAD")) { if (!strcmp(ref->name, "HEAD")) {
head = ref; head = ref;
ref = ref->next; ref = ref->next;
@ -60,17 +61,21 @@ static void write_refs(struct ref *ref)
while (ref) { while (ref) {
if (is_master(ref)) if (is_master(ref))
master_ref = ref; master_ref = ref;
if (head && !memcmp(ref->old_sha1, head->old_sha1, 20)) { if (head &&
if (!head_ptr || ref == master_ref) !memcmp(ref->old_sha1, head->old_sha1, 20) &&
!strncmp(ref->name, "refs/heads/",11) &&
(!head_ptr || ref == master_ref))
head_ptr = ref; head_ptr = ref;
}
write_one_ref(ref); write_one_ref(ref);
ref = ref->next; ref = ref->next;
} }
if (!head) if (!head) {
fprintf(stderr, "No HEAD in remote.\n");
return; return;
}
head_path = git_path("HEAD"); head_path = strdup(git_path("HEAD"));
if (!head_ptr) { if (!head_ptr) {
/* /*
* If we had a master ref, and it wasn't HEAD, we need to undo the * If we had a master ref, and it wasn't HEAD, we need to undo the
@ -82,6 +87,7 @@ static void write_refs(struct ref *ref)
unlink(head_path); unlink(head_path);
} }
write_one_ref(head); write_one_ref(head);
free(head_path);
return; return;
} }
@ -89,13 +95,15 @@ static void write_refs(struct ref *ref)
if (master_ref) if (master_ref)
return; return;
fprintf(stderr, "Setting HEAD to %s\n", head_ptr->name);
/* /*
* Uhhuh. Other end didn't have master. We start HEAD off with * Uhhuh. Other end didn't have master. We start HEAD off with
* the first branch with the same value. * the first branch with the same value.
*/ */
unlink(head_path); if (create_symref(head_path, head_ptr->name) < 0)
if (symlink(head_ptr->name, head_path) < 0)
die("unable to link HEAD to %s", head_ptr->name); die("unable to link HEAD to %s", head_ptr->name);
free(head_path);
} }
static int clone_pack(int fd[2], int nr_match, char **match) static int clone_pack(int fd[2], int nr_match, char **match)

2
diff.h
View file

@ -103,7 +103,7 @@ extern void diff_flush(struct diff_options*);
/* these are not diff-raw status letters proper, but used by /* these are not diff-raw status letters proper, but used by
* diffcore-filter insn to specify additional restrictions. * diffcore-filter insn to specify additional restrictions.
*/ */
#define DIFF_STATUS_FILTER_AON 'A' #define DIFF_STATUS_FILTER_AON '*'
#define DIFF_STATUS_FILTER_BROKEN 'B' #define DIFF_STATUS_FILTER_BROKEN 'B'
#endif /* DIFF_H */ #endif /* DIFF_H */

View file

@ -133,10 +133,13 @@ fi | git-stripspace >.editmsg
case "$signoff" in case "$signoff" in
t) t)
{
echo
git-var GIT_COMMITTER_IDENT | sed -e ' git-var GIT_COMMITTER_IDENT | sed -e '
s/>.*/>/ s/>.*/>/
s/^/Signed-off-by: / s/^/Signed-off-by: /
' >>.editmsg '
} >>.editmsg
;; ;;
esac esac
@ -195,7 +198,7 @@ else
PARENTS="" PARENTS=""
fi fi
git-status >>.editmsg git-status >>.editmsg
if [ "$?" != "0" -a ! -f $GIT_DIR/MERGE_HEAD ] if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
then then
rm -f .editmsg rm -f .editmsg
git-status git-status

View file

@ -1,67 +0,0 @@
#!/bin/sh
# Copyright (C) 2005 Junio C Hamano
#
# This script is designed to emulate what the built-in diff driver
# does when set as GIT_EXTERNAL_SCRIPT.
case "$#" in
1)
echo "* Unmerged path $1"
exit 0 ;;
*)
name1="$1" tmp1="$2" hex1="$3" mode1="$4" tmp2="$5" hex2="$6" mode2="$7"
case "$#" in
7)
name2="$name1" ;;
9)
name2="$8" xfrm_msg="$9" ;;
esac ;;
esac
show_create () {
name_="$1" tmp_="$2" hex_="$3" mode_="$4"
echo "diff --git a/$name_ b/$name_"
echo "new file mode $mode_"
diff ${GIT_DIFF_OPTS-'-pu'} -L /dev/null -L "b/$name_" /dev/null "$tmp_"
}
show_delete () {
name_="$1" tmp_="$2" hex_="$3" mode_="$4"
echo "diff --git a/$name_ b/$name_"
echo "deleted file mode $mode_"
diff ${GIT_DIFF_OPTS-'-pu'} -L "a/$name_" -L /dev/null "$tmp_" /dev/null
}
case "$mode1" in
120*) type1=l ;;
100*) type1=f ;;
.) show_create "$name2" "$tmp2" "$hex2" "$mode2"
exit 0 ;;
esac
case "$mode2" in
120*) type2=l ;;
100*) type2=f ;;
.) show_delete "$name1" "$tmp1" "$hex1" "$mode1"
exit 0 ;;
esac
if test "$type1" != "$type2"
then
show_delete "$name1" "$tmp1" "$hex1" "$mode1"
show_create "$name2" "$tmp2" "$hex2" "$mode2"
exit 0
fi
echo diff --git "a/$name1" "b/$name2"
if test "$mode1" != "$mode2"
then
echo "old mode $mode1"
echo "new mode $mode2"
if test "$xfrm_msg" != ""
then
echo "$xfrm_msg"
fi
fi
diff ${GIT_DIFF_OPTS-'-pu'} -L "a/$name1" -L "b/$name2" "$tmp1" "$tmp2"
exit 0

View file

@ -49,7 +49,7 @@ rsync_slurped_objects=
if test "" = "$append" if test "" = "$append"
then then
: >$GIT_DIR/FETCH_HEAD : >"$GIT_DIR/FETCH_HEAD"
fi fi
append_fetch_head () { append_fetch_head () {
@ -86,11 +86,11 @@ append_fetch_head () {
if git-cat-file commit "$head_" >/dev/null 2>&1 if git-cat-file commit "$head_" >/dev/null 2>&1
then then
headc_=$(git-rev-parse --verify "$head_^0") || exit headc_=$(git-rev-parse --verify "$head_^0") || exit
echo "$headc_ $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
echo >&2 "* committish: $head_" echo >&2 "* committish: $head_"
echo >&2 " $note_" echo >&2 " $note_"
else else
echo "$head_ not-for-merge $note_" >>$GIT_DIR/FETCH_HEAD echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD"
echo >&2 "* non-commit: $head_" echo >&2 "* non-commit: $head_"
echo >&2 " $note_" echo >&2 " $note_"
fi fi

View file

@ -128,10 +128,6 @@ whosepatchScript='
q q
}' }'
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
git-cherry -v "$rev1" "$rev2" | git-cherry -v "$rev1" "$rev2" |
while read sign rev comment while read sign rev comment
do do
@ -216,7 +212,7 @@ Date: '"$ad"
echo echo
git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
echo echo
git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead" git-diff-tree -p $diff_opts "$commit"
case "$mbox" in case "$mbox" in
t) t)

View file

@ -22,14 +22,16 @@ static void remove_lock_file_on_signal(int signo)
int hold_index_file_for_update(struct cache_file *cf, const char *path) int hold_index_file_for_update(struct cache_file *cf, const char *path)
{ {
int fd;
sprintf(cf->lockfile, "%s.lock", path); sprintf(cf->lockfile, "%s.lock", path);
fd = open(cf->lockfile, O_RDWR | O_CREAT | O_EXCL, 0666);
if (fd >=0 && !cf->next) {
cf->next = cache_file_list; cf->next = cache_file_list;
cache_file_list = cf; cache_file_list = cf;
if (!cf->next) {
signal(SIGINT, remove_lock_file_on_signal); signal(SIGINT, remove_lock_file_on_signal);
atexit(remove_lock_file); atexit(remove_lock_file);
} }
return open(cf->lockfile, O_RDWR | O_CREAT | O_EXCL, 0666); return fd;
} }
int commit_index_file(struct cache_file *cf) int commit_index_file(struct cache_file *cf)

2
refs.c
View file

@ -46,7 +46,7 @@ int validate_symref(const char *path)
len -= 4; len -= 4;
while (len && isspace(*buf)) while (len && isspace(*buf))
buf++, len--; buf++, len--;
if (len >= 5 && !memcmp("refs/", buffer, 5)) if (len >= 5 && !memcmp("refs/", buf, 5))
return 0; return 0;
return -1; return -1;
} }

View file

@ -1,4 +1,5 @@
#include "cache.h" #include "cache.h"
#include "refs.h"
#include "tag.h" #include "tag.h"
#include "commit.h" #include "commit.h"
#include "tree.h" #include "tree.h"
@ -489,6 +490,22 @@ static void handle_one_commit(struct commit *com, struct commit_list **lst)
commit_list_insert(com, lst); commit_list_insert(com, lst);
} }
/* for_each_ref() callback does not allow user data -- Yuck. */
static struct commit_list **global_lst;
static int include_one_commit(const char *path, const unsigned char *sha1)
{
struct commit *com = get_commit_reference(path, 0);
handle_one_commit(com, global_lst);
return 0;
}
static void handle_all(struct commit_list **lst)
{
global_lst = lst;
for_each_ref(include_one_commit);
global_lst = NULL;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@ -542,6 +559,10 @@ int main(int argc, char **argv)
bisect_list = 1; bisect_list = 1;
continue; continue;
} }
if (!strcmp(arg, "--all")) {
handle_all(&list);
continue;
}
if (!strcmp(arg, "--objects")) { if (!strcmp(arg, "--objects")) {
tag_objects = 1; tag_objects = 1;
tree_objects = 1; tree_objects = 1;

View file

@ -32,6 +32,7 @@ static int revs_count = 0;
static int is_rev_argument(const char *arg) static int is_rev_argument(const char *arg)
{ {
static const char *rev_args[] = { static const char *rev_args[] = {
"--all",
"--bisect", "--bisect",
"--header", "--header",
"--max-age=", "--max-age=",

View file

@ -30,10 +30,18 @@ static void create_pack_file(void)
if (!pid) { if (!pid) {
int i; int i;
int args = nr_has + nr_needs + 5; int args;
char **argv = xmalloc(args * sizeof(char *)); char **argv;
char *buf = xmalloc(args * 45); char *buf;
char **p = argv; char **p;
if (MAX_NEEDS <= nr_needs)
args = nr_has + 10;
else
args = nr_has + nr_needs + 5;
argv = xmalloc(args * sizeof(char *));
buf = xmalloc(args * 45);
p = argv;
dup2(fd[1], 1); dup2(fd[1], 1);
close(0); close(0);
@ -41,11 +49,15 @@ static void create_pack_file(void)
close(fd[1]); close(fd[1]);
*p++ = "git-rev-list"; *p++ = "git-rev-list";
*p++ = "--objects"; *p++ = "--objects";
if (MAX_NEEDS <= nr_needs)
*p++ = "--all";
else {
for (i = 0; i < nr_needs; i++) { for (i = 0; i < nr_needs; i++) {
*p++ = buf; *p++ = buf;
memcpy(buf, sha1_to_hex(needs_sha1[i]), 41); memcpy(buf, sha1_to_hex(needs_sha1[i]), 41);
buf += 41; buf += 41;
} }
}
for (i = 0; i < nr_has; i++) { for (i = 0; i < nr_has; i++) {
*p++ = buf; *p++ = buf;
*buf++ = '^'; *buf++ = '^';
@ -129,18 +141,24 @@ static int receive_needs(void)
needs = 0; needs = 0;
for (;;) { for (;;) {
unsigned char dummy[20], *sha1_buf;
len = packet_read_line(0, line, sizeof(line)); len = packet_read_line(0, line, sizeof(line));
if (!len) if (!len)
return needs; return needs;
/* sha1_buf = dummy;
* This is purely theoretical right now: git-fetch-pack only if (needs == MAX_NEEDS) {
* ever asks for a single HEAD fprintf(stderr,
*/ "warning: supporting only a max of %d requests. "
if (needs >= MAX_NEEDS) "sending everything instead.\n",
die("I'm only doing a max of %d requests", MAX_NEEDS); MAX_NEEDS);
if (strncmp("want ", line, 5) || get_sha1_hex(line+5, needs_sha1[needs])) }
die("git-upload-pack: protocol error, expected to get sha, not '%s'", line); else if (needs < MAX_NEEDS)
sha1_buf = needs_sha1[needs];
if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf))
die("git-upload-pack: protocol error, "
"expected to get sha, not '%s'", line);
needs++; needs++;
} }
} }