diff options
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | 2006-10-30 20:09:29 +0100 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-11-24 15:42:49 -0800 |
commit | 016e6ccbe03438454777e43dd73d67844296a3fd (patch) | |
tree | f8fa1544f7abf2d4d16217adceaec6901a9635c9 /fetch-pack.c | |
parent | ed09aef06fda2ba06a7412e3fa43ab1c3449f723 (diff) | |
download | git-016e6ccbe03438454777e43dd73d67844296a3fd.tar.gz git-016e6ccbe03438454777e43dd73d67844296a3fd.tar.xz |
allow cloning a repository "shallowly"
By specifying a depth, you can now clone a repository such that
all fetched ancestor-chains' length is at most "depth". For example,
if the upstream repository has only 2 branches ("A" and "B"), which
are linear, and you specify depth 3, you will get A, A~1, A~2, A~3,
B, B~1, B~2, and B~3. The ends are automatically made shallow
commits.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'fetch-pack.c')
-rw-r--r-- | fetch-pack.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/fetch-pack.c b/fetch-pack.c index bc5e72505..f335bd42b 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -11,8 +11,9 @@ static int keep_pack; static int quiet; static int verbose; static int fetch_all; +static int depth; static const char fetch_pack_usage[] = -"git-fetch-pack [--all] [-q] [-v] [-k] [--thin] [--exec=upload-pack] [host:]directory <refs>..."; +"git-fetch-pack [--all] [-q] [-v] [-k] [--thin] [--exec=upload-pack] [--depth=<n>] [host:]directory <refs>..."; static const char *exec = "git-upload-pack"; #define COMPLETE (1U << 0) @@ -182,10 +183,29 @@ static int find_common(int fd[2], unsigned char *result_sha1, } if (is_repository_shallow()) write_shallow_commits(fd[1], 1); + if (depth > 0) + packet_write(fd[1], "deepen %d", depth); packet_flush(fd[1]); if (!fetching) return 1; + if (depth > 0) { + char line[1024]; + unsigned char sha1[20]; + int len; + + while ((len = packet_read_line(fd[0], line, sizeof(line)))) { + if (!strncmp("shallow ", line, 8)) { + if (get_sha1_hex(line + 8, sha1)) + die("invalid shallow line: %s", line); + /* no need making it shallow if we have it already */ + if (lookup_object(sha1)) + continue; + register_shallow(sha1); + } + } + } + flushes = 0; retval = -1; while ((sha1 = get_rev())) { @@ -576,6 +596,8 @@ int main(int argc, char **argv) char *dest = NULL, **heads; int fd[2]; pid_t pid; + struct stat st; + struct lock_file lock; setup_git_directory(); @@ -609,6 +631,12 @@ int main(int argc, char **argv) verbose = 1; continue; } + if (!strncmp("--depth=", arg, 8)) { + depth = strtol(arg + 8, NULL, 0); + if (stat(git_path("shallow"), &st)) + st.st_mtime = 0; + continue; + } usage(fetch_pack_usage); } dest = arg; @@ -618,6 +646,8 @@ int main(int argc, char **argv) } 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; @@ -639,5 +669,34 @@ int main(int argc, char **argv) } } + if (!ret && depth > 0) { + struct cache_time mtime; + char *shallow = git_path("shallow"); + int fd; + + mtime.sec = st.st_mtime; +#ifdef USE_NSEC + mtime.usec = st.st_mtim.usec; +#endif + if (stat(shallow, &st)) { + if (mtime.sec) + die("shallow file was removed during fetch"); + } else if (st.st_mtime != mtime.sec +#ifdef USE_NSEC + || st.st_mtim.usec != mtime.usec +#endif + ) + die("shallow file was changed during fetch"); + + fd = hold_lock_file_for_update(&lock, shallow, 1); + if (!write_shallow_commits(fd, 0)) { + unlink(lock.filename); + rollback_lock_file(&lock); + } else { + close(fd); + commit_lock_file(&lock); + } + } + return !!ret; } |