summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 016e6cc)
raw | patch | inline | side by side (parent: 016e6cc)
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | |
Mon, 30 Oct 2006 19:09:53 +0000 (20:09 +0100) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Fri, 24 Nov 2006 23:42:49 +0000 (15:42 -0800) |
Now, by saying "git fetch -depth <n> <repo>" you can deepen
a shallow repository.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
a shallow repository.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
commit.c | patch | blob | history | |
commit.h | patch | blob | history | |
fetch-pack.c | patch | blob | history | |
git-fetch.sh | patch | blob | history | |
shallow.c | patch | blob | history | |
upload-pack.c | patch | blob | history |
diff --git a/commit.c b/commit.c
index bffa278868f13b8ba3ba72d45c3dee9eb813fca8..d5103cd3c6358bea2acc8040dfb6eb3afd273420 100644 (file)
--- a/commit.c
+++ b/commit.c
return count;
}
+int unregister_shallow(const unsigned char *sha1)
+{
+ int pos = commit_graft_pos(sha1);
+ if (pos < 0)
+ return -1;
+ if (pos + 1 < commit_graft_nr)
+ memcpy(commit_graft + pos, commit_graft + pos + 1,
+ sizeof(struct commit_graft *)
+ * (commit_graft_nr - pos - 1));
+ commit_graft_nr--;
+ return 0;
+}
+
int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
{
char *tail = buffer;
diff --git a/commit.h b/commit.h
index c559510b46d7aa84187b616be1ed7654a0447ec8..e9e158f4e1c670635dda02766f67da3821374669 100644 (file)
--- a/commit.h
+++ b/commit.h
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
extern int register_shallow(const unsigned char *sha1);
+extern int unregister_shallow(const unsigned char *sha1);
extern int write_shallow_commits(int fd, int use_pack_protocol);
extern int is_repository_shallow();
extern struct commit_list *get_shallow_commits(struct object_array *heads,
- int depth);
+ int depth, int shallow_flag, int not_shallow_flag);
#endif /* COMMIT_H */
diff --git a/fetch-pack.c b/fetch-pack.c
index f335bd42b7b61429a307b0d6930987f1058c8034..c3064b94ad1d9e682014a83eb46349af5733e295 100644 (file)
--- a/fetch-pack.c
+++ b/fetch-pack.c
if (lookup_object(sha1))
continue;
register_shallow(sha1);
- }
+ } else if (!strncmp("unshallow ", line, 10)) {
+ if (get_sha1_hex(line + 10, sha1))
+ die("invalid unshallow line: %s", line);
+ if (!lookup_object(sha1))
+ die("object not found: %s", line);
+ /* make sure that it is parsed as shallow */
+ parse_object(sha1);
+ if (unregister_shallow(sha1))
+ die("no shallow found: %s", line);
+ } else
+ die("expected shallow/unshallow, got %s", line);
}
}
}
}
- for_each_ref(mark_complete, NULL);
- if (cutoff)
- mark_recent_complete_commits(cutoff);
+ if (!depth) {
+ for_each_ref(mark_complete, NULL);
+ if (cutoff)
+ mark_recent_complete_commits(cutoff);
+ }
/*
* Mark all complete remote refs as common refs.
}
if (!dest)
usage(fetch_pack_usage);
- if (is_repository_shallow() && depth > 0)
- die("Deepening of a shallow repository not yet supported!");
pid = git_connect(fd, dest, exec);
if (pid < 0)
return 1;
diff --git a/git-fetch.sh b/git-fetch.sh
index eb32476bbdc98cc9a34d4026575e4d1a608289be..0b1e6d1071350af34e95a402d7ef53f00d03d8a4 100755 (executable)
--- a/git-fetch.sh
+++ b/git-fetch.sh
exec=
upload_pack=
keep=
+shallow_depth=
while case "$#" in 0) break ;; esac
do
case "$1" in
--reflog-action=*)
rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
;;
+ --depth=*)
+ shallow_depth="--depth=`expr "z$1" : 'z-[^=]*=\(.*\)'`"
+ ;;
+ --depth)
+ shift
+ shallow_depth="--depth=$1"
+ ;;
-*)
usage
;;
# There are transports that can fetch only one head at a time...
case "$remote" in
http://* | https://* | ftp://*)
+ test -n "$shallow_depth" &&
+ die "shallow clone with http not supported"
proto=`expr "$remote" : '\([^:]*\):'`
if [ -n "$GIT_SSL_NO_VERIFY" ]; then
curl_extra_args="-k"
git-http-fetch -v -a "$head" "$remote/" || exit
;;
rsync://*)
+ test -n "$shallow_depth" &&
+ die "shallow clone with rsync not supported"
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
head=$(git-rev-parse --verify TMP_HEAD)
pack_lockfile=
IFS=" $LF"
(
- git-fetch-pack --thin $exec $keep "$remote" $rref || echo failed "$remote"
+ git-fetch-pack --thin $exec $keep $shallow_depth "$remote" $rref || echo failed "$remote"
) |
while read sha1 remote_name
do
diff --git a/shallow.c b/shallow.c
index 3cf2127134787586ac30e16764f6b639fa315a59..58a7b20d793cbc71ab924d5f5aedf28cd01ca32a 100644 (file)
--- a/shallow.c
+++ b/shallow.c
return is_shallow;
}
-struct commit_list *get_shallow_commits(struct object_array *heads, int depth)
+struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
+ int shallow_flag, int not_shallow_flag)
{
int i = 0, cur_depth = 0;
struct commit_list *result = NULL;
}
}
parse_commit(commit);
+ commit->object.flags |= not_shallow_flag;
cur_depth++;
for (p = commit->parents, commit = NULL; p; p = p->next) {
if (!p->item->util) {
commit = p->item;
cur_depth = *(int *)commit->util;
}
- } else
+ } else {
commit_list_insert(p->item, &result);
+ p->item->object.flags |= shallow_flag;
+ }
}
}
diff --git a/upload-pack.c b/upload-pack.c
index ebe1e5ae4d12eb32dbd14eb40ee1c1e5d21bb100..4a9d6720a5a0e9977bd9346e649666ead4e18fe4 100644 (file)
--- a/upload-pack.c
+++ b/upload-pack.c
#define COMMON_KNOWN (1u << 14)
#define REACHABLE (1u << 15)
+#define SHALLOW (1u << 16)
+#define NOT_SHALLOW (1u << 17)
+#define CLIENT_SHALLOW (1u << 18)
+
static unsigned long oldest_have;
static int multi_ack, nr_our_refs;
} else {
for (i = 0; i < want_obj.nr; i++) {
struct object *o = want_obj.objects[i].item;
+ o->flags &= ~UNINTERESTING;
add_pending_object(&revs, o, NULL);
}
for (i = 0; i < have_obj.nr; i++) {
if (!strncmp("shallow ", line, 8)) {
unsigned char sha1[20];
struct object *object;
+ use_thin_pack = 0;
if (get_sha1(line + 8, sha1))
die("invalid shallow line: %s", line);
object = parse_object(sha1);
if (!object)
die("did not find object for %s", line);
+ object->flags |= CLIENT_SHALLOW;
add_object_array(object, NULL, &shallows);
continue;
}
if (!strncmp("deepen ", line, 7)) {
char *end;
+ use_thin_pack = 0;
depth = strtol(line + 7, &end, 0);
if (end == line + 7 || depth <= 0)
die("Invalid deepen: %s", line);
add_object_array(o, NULL, &want_obj);
}
}
+ if (depth == 0 && shallows.nr == 0)
+ return;
if (depth > 0) {
struct commit_list *result, *backup;
- if (shallows.nr > 0)
- die("Deepening a shallow repository not yet supported");
- backup = result = get_shallow_commits(&want_obj, depth);
+ int i;
+ backup = result = get_shallow_commits(&want_obj, depth,
+ SHALLOW, NOT_SHALLOW);
while (result) {
- packet_write(1, "shallow %s",
- sha1_to_hex(result->item->object.sha1));
+ struct object *object = &result->item->object;
+ if (!(object->flags & CLIENT_SHALLOW)) {
+ packet_write(1, "shallow %s",
+ sha1_to_hex(object->sha1));
+ register_shallow(object->sha1);
+ }
result = result->next;
}
free_commit_list(backup);
- }
- if (shallows.nr > 0) {
- int i;
- for (i = 0; i < shallows.nr; i++)
- register_shallow(shallows.objects[i].item->sha1);
- }
+ for (i = 0; i < shallows.nr; i++) {
+ struct object *object = shallows.objects[i].item;
+ if (object->flags & NOT_SHALLOW) {
+ struct commit_list *parents;
+ packet_write(1, "unshallow %s",
+ sha1_to_hex(object->sha1));
+ object->flags &= ~CLIENT_SHALLOW;
+ /* make sure the real parents are parsed */
+ unregister_shallow(object->sha1);
+ parse_commit((struct commit *)object);
+ parents = ((struct commit *)object)->parents;
+ while (parents) {
+ add_object_array(&parents->item->object,
+ NULL, &want_obj);
+ parents = parents->next;
+ }
+ }
+ /* make sure commit traversal conforms to client */
+ register_shallow(object->sha1);
+ }
+ packet_flush(1);
+ } else
+ if (shallows.nr > 0) {
+ int i;
+ for (i = 0; i < shallows.nr; i++)
+ register_shallow(shallows.objects[i].item->sha1);
+ }
+ free(shallows.objects);
}
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)