summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-04-26 08:20:50 (GMT)
committerJunio C Hamano <junkio@cox.net>2006-05-02 05:29:16 (GMT)
commit6bd20358a9b831b3b545284188871bc844245c25 (patch)
tree421b2749edc4442cda4f455e8c157a229f287ad9
parentf4c6f2d328e2f30ad63fdfca26a5e4a11cef35bf (diff)
downloadgit-6bd20358a9b831b3b545284188871bc844245c25.zip
git-6bd20358a9b831b3b545284188871bc844245c25.tar.gz
git-6bd20358a9b831b3b545284188871bc844245c25.tar.bz2
write-tree: --prefix=<path>
The "bind" commit can express an aggregation of multiple projects into a single commit. In such an organization, there would be one project, root of whose tree object is at the same level of the root of the aggregated projects, and other projects have their toplevel in separate subdirectories. Let's call that root level project the "primary project", and call other ones just "subprojects". You would first read-tree the primary project, and then graft the subprojects under their appropriate location using read-tree --prefix=<subdir>/ repeatedly. To write out a tree object from such an index for a subproject, write-tree --prefix=<subdir>/ is used. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--Documentation/git-write-tree.txt8
-rw-r--r--cache-tree.c26
-rw-r--r--cache-tree.h2
-rwxr-xr-xt/t0000-basic.sh14
-rw-r--r--write-tree.c23
5 files changed, 67 insertions, 6 deletions
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index 77e12cb..c85fa89 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -8,7 +8,7 @@ git-write-tree - Creates a tree object from the current index
SYNOPSIS
--------
-'git-write-tree' [--missing-ok]
+'git-write-tree' [--missing-ok] [--prefix=<prefix>/]
DESCRIPTION
-----------
@@ -30,6 +30,12 @@ OPTIONS
directory exist in the object database. This option disables this
check.
+--prefix=<prefix>/::
+ Writes a tree object that represents a subdirectory
+ `<prefix>`. This can be used to write the tree object
+ for a subproject that is in the named subdirectory.
+
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
diff --git a/cache-tree.c b/cache-tree.c
index e452238..dae4399 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -525,3 +525,29 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
return NULL; /* not the whole tree */
return read_one(&buffer, &size);
}
+
+struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
+{
+ while (*path) {
+ const char *slash;
+ struct cache_tree_sub *sub;
+
+ slash = strchr(path, '/');
+ if (!slash)
+ slash = path + strlen(path);
+ /* between path and slash is the name of the
+ * subtree to look for.
+ */
+ sub = find_subtree(it, path, slash - path, 0);
+ if (!sub)
+ return NULL;
+ it = sub->cache_tree;
+ if (slash)
+ while (*slash && *slash == '/')
+ slash++;
+ if (!slash || !*slash)
+ return it; /* prefix ended with slashes */
+ path = slash;
+ }
+ return it;
+}
diff --git a/cache-tree.h b/cache-tree.h
index 72c6480..119407e 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -28,4 +28,6 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
int cache_tree_fully_valid(struct cache_tree *);
int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int);
+struct cache_tree *cache_tree_find(struct cache_tree *, const char *);
+
#endif
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index cf33989..2c9bbb5 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -195,6 +195,20 @@ test_expect_success \
'git-ls-tree -r output for a known tree.' \
'diff current expected'
+test_expect_success \
+ 'writing partial tree out with git-write-tree --prefix.' \
+ 'ptree=$(git-write-tree --prefix=path3)'
+test_expect_success \
+ 'validate object ID for a known tree.' \
+ 'test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3'
+
+test_expect_success \
+ 'writing partial tree out with git-write-tree --prefix.' \
+ 'ptree=$(git-write-tree --prefix=path3/subp3)'
+test_expect_success \
+ 'validate object ID for a known tree.' \
+ 'test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2'
+
################################################################
rm .git/index
test_expect_success \
diff --git a/write-tree.c b/write-tree.c
index 7a4f691..895e7a3 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -8,8 +8,10 @@
#include "cache-tree.h"
static int missing_ok = 0;
+static char *prefix = NULL;
-static const char write_tree_usage[] = "git-write-tree [--missing-ok]";
+static const char write_tree_usage[] =
+"git-write-tree [--missing-ok] [--prefix=<prefix>/]";
static struct cache_file cache_file;
@@ -21,13 +23,18 @@ int main(int argc, char **argv)
newfd = hold_index_file_for_update(&cache_file, get_index_file());
entries = read_cache();
- if (argc == 2) {
- if (!strcmp(argv[1], "--missing-ok"))
+
+ while (1 < argc) {
+ char *arg = argv[1];
+ if (!strcmp(arg, "--missing-ok"))
missing_ok = 1;
+ else if (!strncmp(arg, "--prefix=", 9))
+ prefix = arg + 9;
else
die(write_tree_usage);
+ argc--; argv++;
}
-
+
if (argc > 2)
die("too many options");
@@ -54,6 +61,12 @@ int main(int argc, char **argv)
* performance penalty and not a big deal.
*/
}
- printf("%s\n", sha1_to_hex(active_cache_tree->sha1));
+ if (prefix) {
+ struct cache_tree *subtree =
+ cache_tree_find(active_cache_tree, prefix);
+ printf("%s\n", sha1_to_hex(subtree->sha1));
+ }
+ else
+ printf("%s\n", sha1_to_hex(active_cache_tree->sha1));
return 0;
}