projects
/
git.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
diff-delta.c: allow delta with empty blob.
[git.git]
/
send-pack.c
diff --git
a/send-pack.c
b/send-pack.c
index
4d015fd
..
f61c15c
100644
(file)
--- a/
send-pack.c
+++ b/
send-pack.c
@@
-105,36
+105,53
@@
static int pack_objects(int fd, struct ref *refs)
return 0;
}
return 0;
}
+static void unmark_and_free(struct commit_list *list, unsigned int mark)
+{
+ while (list) {
+ struct commit_list *temp = list;
+ temp->item->object.flags &= ~mark;
+ list = temp->next;
+ free(temp);
+ }
+}
+
static int ref_newer(const unsigned char *new_sha1,
const unsigned char *old_sha1)
{
struct object *o;
struct commit *old, *new;
static int ref_newer(const unsigned char *new_sha1,
const unsigned char *old_sha1)
{
struct object *o;
struct commit *old, *new;
- struct commit_list *list;
+ struct commit_list *list, *used;
+ int found = 0;
/* Both new and old must be commit-ish and new is descendant of
* old. Otherwise we require --force.
*/
/* Both new and old must be commit-ish and new is descendant of
* old. Otherwise we require --force.
*/
- o = deref_tag(parse_object(old_sha1));
+ o = deref_tag(parse_object(old_sha1)
, NULL, 0
);
if (!o || o->type != commit_type)
return 0;
old = (struct commit *) o;
if (!o || o->type != commit_type)
return 0;
old = (struct commit *) o;
- o = deref_tag(parse_object(new_sha1));
+ o = deref_tag(parse_object(new_sha1)
, NULL, 0
);
if (!o || o->type != commit_type)
return 0;
new = (struct commit *) o;
if (parse_commit(new) < 0)
return 0;
if (!o || o->type != commit_type)
return 0;
new = (struct commit *) o;
if (parse_commit(new) < 0)
return 0;
- list = NULL;
+
+ used = list = NULL;
commit_list_insert(new, &list);
while (list) {
new = pop_most_recent_commit(&list, 1);
commit_list_insert(new, &list);
while (list) {
new = pop_most_recent_commit(&list, 1);
- if (new == old)
- return 1;
+ commit_list_insert(new, &used);
+ if (new == old) {
+ found = 1;
+ break;
+ }
}
}
- return 0;
+ unmark_and_free(list, 1);
+ unmark_and_free(used, 1);
+ return found;
}
static struct ref *local_refs, **local_tail;
}
static struct ref *local_refs, **local_tail;
@@
-164,7
+181,7
@@
static int send_pack(int in, int out, int nr_refspec, char **refspec)
int new_refs;
/* No funny business with the matcher */
int new_refs;
/* No funny business with the matcher */
- remote_tail = get_remote_heads(in, &remote_refs, 0, NULL);
+ remote_tail = get_remote_heads(in, &remote_refs, 0, NULL
, 1
);
get_local_heads();
/* match them up */
get_local_heads();
/* match them up */
@@
-173,6
+190,12
@@
static int send_pack(int in, int out, int nr_refspec, char **refspec)
if (match_refs(local_refs, remote_refs, &remote_tail,
nr_refspec, refspec, send_all))
return -1;
if (match_refs(local_refs, remote_refs, &remote_tail,
nr_refspec, refspec, send_all))
return -1;
+
+ if (!remote_refs) {
+ fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
+ return 0;
+ }
+
/*
* Finally, tell the other end!
*/
/*
* Finally, tell the other end!
*/
@@
-189,7
+212,8
@@
static int send_pack(int in, int out, int nr_refspec, char **refspec)
/* This part determines what can overwrite what.
* The rules are:
*
/* This part determines what can overwrite what.
* The rules are:
*
- * (0) you can always use --force.
+ * (0) you can always use --force or +A:B notation to
+ * selectively force individual ref pairs.
*
* (1) if the old thing does not exist, it is OK.
*
*
* (1) if the old thing does not exist, it is OK.
*
@@
-201,16
+225,19
@@
static int send_pack(int in, int out, int nr_refspec, char **refspec)
* descendant of old, it is OK.
*/
* descendant of old, it is OK.
*/
- if (!force_update && !is_zero_sha1(ref->old_sha1)) {
+ if (!force_update &&
+ !is_zero_sha1(ref->old_sha1) &&
+ !ref->force) {
if (!has_sha1_file(ref->old_sha1)) {
error("remote '%s' object %s does not "
"exist on local",
ref->name, sha1_to_hex(ref->old_sha1));
continue;
}
if (!has_sha1_file(ref->old_sha1)) {
error("remote '%s' object %s does not "
"exist on local",
ref->name, sha1_to_hex(ref->old_sha1));
continue;
}
+
/* We assume that local is fsck-clean. Otherwise
/* We assume that local is fsck-clean. Otherwise
- * you _could_ have a old tag which points at
- * something you do not have which may or may not
+ * you _could_ have a
n
old tag which points at
+ * something you do not have
,
which may or may not
* be a commit.
*/
if (!ref_newer(ref->peer_ref->new_sha1,
* be a commit.
*/
if (!ref_newer(ref->peer_ref->new_sha1,
@@
-252,6
+279,7
@@
int main(int argc, char **argv)
int fd[2], ret;
pid_t pid;
int fd[2], ret;
pid_t pid;
+ setup_git_directory();
argv++;
for (i = 1; i < argc; i++, argv++) {
char *arg = *argv;
argv++;
for (i = 1; i < argc; i++, argv++) {
char *arg = *argv;