git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: "Shawn O. Pearce" <spearce@spearce.org>,
	Sverre Rabbelier <srabbelier@gmail.com>,
	David Barr <david.barr@cordelta.com>,
	Ramkumar Ramachandra <artagnon@gmail.com>
Subject: [PATCH/RFC] Teach fast-import to import subtrees named by tree id
Date: Wed, 30 Jun 2010 22:18:19 -0500	[thread overview]
Message-ID: <20100701031819.GA12524@burratino> (raw)

To simulate the svn cp command, it would be very useful to be
replace an arbitrary file in the current revision by an
arbitrary directory from a previous one.  Modify the filemodify
command to allow that:

 M 040000 <tree id> pathname

This would be most useful in combination with a facility to
print the commit ids for new revisions as they are written.

Cc: Shawn O. Pearce <spearce@spearce.org>
Cc: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
I actually thought fast-import already did this until David
mentioned that no, it does not.  Well, live and learn.

This and Sverre’s --print-marks command would allow svn-fe
to be simplified a great deal.

I was not sure whether to add a "feature" specification for
this, so I’ll try that as a separate patch.

Thoughts?
Jonathan

 Documentation/git-fast-import.txt |    8 ++++-
 fast-import.c                     |   24 ++++++++++------
 t/t9300-fast-import.sh            |   54 +++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 19082b0..f4d9aeb 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -482,9 +482,11 @@ External data format::
 	'M' SP <mode> SP <dataref> SP <path> LF
 ....
 +
-Here `<dataref>` can be either a mark reference (`:<idnum>`)
+Here usually `<dataref>` must be either a mark reference (`:<idnum>`)
 set by a prior `blob` command, or a full 40-byte SHA-1 of an
-existing Git blob object.
+existing Git blob object.  If `<mode>` is `040000`` then
+`<dataref>` must be the full 40-byte SHA-1 of an existing
+Git tree object or a mark reference set with `--import-marks`.
 
 Inline data format::
 	The data content for the file has not been supplied yet.
@@ -509,6 +511,8 @@ in octal.  Git only supports the following modes:
 * `160000`: A gitlink, SHA-1 of the object refers to a commit in
   another repository. Git links can only be specified by SHA or through
   a commit mark. They are used to implement submodules.
+* `040000`: A subdirectory.  Subdirectories can only be specified by
+  SHA or through a tree mark set with `--import-marks`.
 
 In both formats `<path>` is the complete path of the file to be added
 (if not already existing) or modified (if already existing).
diff --git a/fast-import.c b/fast-import.c
index 1e5d66e..ad6843a 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2131,6 +2131,7 @@ static void file_change_m(struct branch *b)
 	case S_IFREG | 0644:
 	case S_IFREG | 0755:
 	case S_IFLNK:
+	case S_IFDIR:
 	case S_IFGITLINK:
 		/* ok */
 		break;
@@ -2176,23 +2177,28 @@ static void file_change_m(struct branch *b)
 		 * another repository.
 		 */
 	} else if (inline_data) {
+		if (S_ISDIR(mode))
+			die("Directories cannot be specified 'inline': %s",
+				command_buf.buf);
 		if (p != uq.buf) {
 			strbuf_addstr(&uq, p);
 			p = uq.buf;
 		}
 		read_next_command();
 		parse_and_store_blob(&last_blob, sha1, 0);
-	} else if (oe) {
-		if (oe->type != OBJ_BLOB)
-			die("Not a blob (actually a %s): %s",
-				typename(oe->type), command_buf.buf);
 	} else {
-		enum object_type type = sha1_object_info(sha1, NULL);
+		enum object_type expected = S_ISDIR(mode) ?
+						OBJ_TREE: OBJ_BLOB;
+		enum object_type type = oe ? oe->type :
+					sha1_object_info(sha1, NULL);
 		if (type < 0)
-			die("Blob not found: %s", command_buf.buf);
-		if (type != OBJ_BLOB)
-			die("Not a blob (actually a %s): %s",
-			    typename(type), command_buf.buf);
+			die("%s not found: %s",
+					S_ISDIR(mode) ?  "Tree" : "Blob",
+					command_buf.buf);
+		if (type != expected)
+			die("Not a %s (actually a %s): %s",
+				typename(expected), typename(type),
+				command_buf.buf);
 	}
 
 	tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 131f032..50d5913 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -796,6 +796,60 @@ test_expect_success \
 	'git fast-import <input &&
 	 test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`'
 
+test_expect_success \
+	'N: copy directory by id' \
+	'cat >expect <<-\EOF &&
+	:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100	file2/newf	file3/newf
+	:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100	file2/oldf	file3/oldf
+	EOF
+	 subdir=$(git rev-parse refs/heads/branch^0:file2) &&
+	 cat >input <<-INPUT_END &&
+	commit refs/heads/N4
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	copy by tree hash
+	COMMIT
+
+	from refs/heads/branch^0
+	M 040000 $subdir file3
+	INPUT_END
+	 git fast-import <input &&
+	 git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
+	 compare_diff_raw expect actual'
+
+test_expect_success \
+	'N: modify copied tree' \
+	'cat >expect <<-\EOF &&
+	:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100	newdir/interesting	file3/file5
+	:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100	file2/newf	file3/newf
+	:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100	file2/oldf	file3/oldf
+	EOF
+	 subdir=$(git rev-parse refs/heads/branch^0:file2) &&
+	 cat >input <<-INPUT_END &&
+	commit refs/heads/N5
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	copy by tree hash
+	COMMIT
+
+	from refs/heads/branch^0
+	M 040000 $subdir file3
+
+	commit refs/heads/N5
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	modify directory copy
+	COMMIT
+
+	M 644 inline file3/file5
+	data <<EOF
+	$file5_data
+	EOF
+	INPUT_END
+	 git fast-import <input &&
+	 git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
+	 compare_diff_raw expect actual'
+
 ###
 ### series O
 ###
-- 
1.7.1.1

             reply	other threads:[~2010-07-01  3:18 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-01  3:18 Jonathan Nieder [this message]
2010-07-01  5:48 ` [WIP/PATCH] Teach fast-import to print the id of each imported commit Jonathan Nieder
2010-07-02  3:16   ` Sverre Rabbelier
2010-07-02  3:41     ` Jonathan Nieder
2010-07-02  4:29       ` Sverre Rabbelier
2010-07-02  5:12   ` Jonathan Nieder
2010-07-02 14:55     ` Sverre Rabbelier
2010-07-02 15:40       ` Jonathan Nieder
2010-07-02 15:48         ` Sverre Rabbelier
2010-07-04  0:02         ` Sam Vilain
2010-07-04  0:35           ` Jonathan Nieder
2010-07-04  3:44             ` Sam Vilain
2010-07-04  7:22               ` Jonathan Nieder
2010-08-17 17:02   ` Ramkumar Ramachandra
2010-09-05  3:15     ` [RFC/PATCH 0/3] fast-import: give importers access to the object store Jonathan Nieder
2010-09-05  3:22       ` [PATCH 1/3] t9300 (fast-import): style tweaks Jonathan Nieder
2010-09-24  6:59         ` [PATCH/RFC 00/24] " Jonathan Nieder
2010-09-24  7:04           ` [PATCH 01/24] t9300 (fast-import): avoid exiting early on failure Jonathan Nieder
2010-09-24  7:05           ` [PATCH 02/24] t9300 (fast-import): avoid hard-coded object names Jonathan Nieder
2010-09-24  7:09           ` [PATCH 03/24] t9300 (fast-import): guard "export large marks" test setup Jonathan Nieder
2010-09-24  9:38             ` Ramkumar Ramachandra
2010-09-24 10:56               ` Raja R Harinath
2010-09-24 10:34             ` Ramkumar Ramachandra
2010-09-24 11:01               ` Raja R Harinath
2010-09-24  7:11           ` [PATCH 04/24] t9300 (fast-import): check exit status from upstream of pipes Jonathan Nieder
2010-09-24  7:11           ` [PATCH 05/24] t9300 (fast-import): check exit status from command substitutions Jonathan Nieder
2010-09-24  7:12           ` [PATCH 06/24] t9300 (fast-import): use test_cmp in place of test $(foo) = $(bar) Jonathan Nieder
2010-09-24  7:13           ` [PATCH 07/24] t9300 (fast-import): use tabs to indent Jonathan Nieder
2010-09-24  8:54             ` Ramkumar Ramachandra
2010-09-24  9:21               ` Jonathan Nieder
2010-09-24  7:16           ` [PATCH 08/24] t9300 (fast-import), series A: re-indent Jonathan Nieder
2010-09-24  7:22             ` Sverre Rabbelier
2010-09-24  7:35               ` Jonathan Nieder
2010-09-24  7:18           ` [PATCH 09/24] t9300 (fast-import), series B: re-indent Jonathan Nieder
2010-09-24  7:19           ` [PATCH 10/24] t9300 (fast-import), series C: re-indent Jonathan Nieder
2010-09-24  7:19           ` [PATCH 11/24] t9300 (fast-import), series D: re-indent Jonathan Nieder
2010-09-24  7:21           ` [PATCH 12/24] t9300 (fast-import), series E: re-indent Jonathan Nieder
2010-09-24  7:22           ` [PATCH 13/24] t9300 (fast-import), series F: re-indent Jonathan Nieder
2010-09-24  7:22           ` [PATCH 14/24] t9300 (fast-import), series H: re-indent Jonathan Nieder
2010-09-24  7:23           ` [PATCH 15/24] t9300 (fast-import), series I: re-indent Jonathan Nieder
2010-09-24  7:24           ` [PATCH 16/24] t9300 (fast-import), series J: re-indent Jonathan Nieder
2010-09-24  7:25           ` [PATCH 17/24] t9300 (fast-import), series K: re-indent Jonathan Nieder
2010-09-24  7:25           ` [PATCH 18/24] t9300 (fast-import), series L: re-indent Jonathan Nieder
2010-09-24  7:26           ` [PATCH 19/24] t9300 (fast-import), series M: re-indent Jonathan Nieder
2010-09-24  7:26           ` [PATCH 20/24] t9300 (fast-import), series N: re-indent Jonathan Nieder
2010-09-24  7:27           ` [PATCH 21/24] t9300 (fast-import), series O: re-indent Jonathan Nieder
2010-09-24  7:27           ` [PATCH 22/24] t9300 (fast-import), series P: re-indent Jonathan Nieder
2010-09-24  7:28           ` [PATCH 23/24] t9300 (fast-import), series Q: re-indent Jonathan Nieder
2010-09-24  7:30           ` [PATCH 24/24] t9300 (fast-import), series R: re-indent Jonathan Nieder
2010-09-25  5:19           ` svn-fe status Jonathan Nieder
2010-09-25 10:25             ` Sverre Rabbelier
2010-09-27  2:54               ` Jonathan Nieder
2010-09-27  9:15                 ` Sverre Rabbelier
2010-09-05  3:29       ` [PATCH 2/3] Teach fast-import to print the id of each imported commit Jonathan Nieder
2010-09-05  3:41       ` [PATCH 3/3] fast-import: Let importers retrieve the objects being written Jonathan Nieder
2010-09-05  6:08       ` [RFC/PATCH 0/3] fast-import: give importers access to the object store Ramkumar Ramachandra
2010-09-05  6:28         ` Sverre Rabbelier
2010-09-05  8:47           ` Ramkumar Ramachandra
2010-09-05 16:20             ` Sverre Rabbelier
2010-09-05 17:31         ` Jonathan Nieder
2010-09-08  3:13       ` [PATCH 4/3] fast-import: typofix Jonathan Nieder
2010-09-08  3:17       ` [PATCH 5/3] fast-import: allow cat command with empty path Jonathan Nieder
2010-09-08  3:27       ` [PATCH 6/3] fast-import: Allow cat requests at arbitrary points in stream Jonathan Nieder
2010-09-08  3:38         ` Sverre Rabbelier
2010-09-08  3:57           ` Jonathan Nieder
2010-09-08 10:16         ` Ramkumar Ramachandra
2010-09-16  0:14       ` [RFC/PATCH 0/3] fast-import: give importers access to the object store Sam Vilain
2010-09-17 23:24         ` Sverre Rabbelier
2010-09-24 19:43         ` Jonathan Nieder
2010-09-24 23:44           ` Sverre Rabbelier
2010-09-25  0:01             ` Jonathan Nieder
2010-09-25  0:17               ` Sverre Rabbelier
2010-07-02  3:20 ` [PATCH/RFC] Teach fast-import to import subtrees named by tree id Sverre Rabbelier
2010-07-02  4:42   ` Jonathan Nieder
2010-07-02 12:44 ` Ramkumar Ramachandra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100701031819.GA12524@burratino \
    --to=jrnieder@gmail.com \
    --cc=artagnon@gmail.com \
    --cc=david.barr@cordelta.com \
    --cc=git@vger.kernel.org \
    --cc=spearce@spearce.org \
    --cc=srabbelier@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).