# [PATCH] Add --path-prefix option to git-fast-import

4 messages from 2009-12-29 to 2009-12-30. Participants: Gisle Aas, Sverre Rabbelier, Shawn O. Pearce.
Thread: https://gitlist.dev/t/22050

## Gisle Aas, 2009-12-29 12:51

Subject: [PATCH] Add --path-prefix option to git-fast-import
Message-ID: <1262091083-25401-1-git-send-email-gisle.aas@it.uib.no>
URL: https://gitlist.dev/e/1262091083-25401-1-git-send-email-gisle.aas%40it.uib.no

```
From: Gisle Aas <gisle@aas.no>

I found this useful when import multiple external repositories to be merged
into a single git repo.  Not having the files be renamed during the merge
made it easier to follow the history of the individual files.

Signed-off-by: Gisle Aas <gisle@aas.no>
---
 Documentation/git-fast-import.txt |    6 ++++++
 fast-import.c                     |   24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 288032c..b8f9593 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -58,6 +58,12 @@ OPTIONS
 	Maximum number of branches to maintain active at once.
 	See ``Memory Utilization'' below for details.  Default is 5.
 
+--path-prefix=<str>:
+	Prepend the given prefix to all the paths imported.
+	This can be used to import stuff into a subdirectory
+	of where the original files where located.  Most likely
+	you want <str> to end with a slash.
+
 --export-marks=<file>::
 	Dumps the internal marks table to <file> when complete.
 	Marks are written one per line as `:markid SHA-1`.
diff --git a/fast-import.c b/fast-import.c
index dd3c99d..32b0d70 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -351,6 +351,8 @@ static struct recent_command *rc_free;
 static unsigned int cmd_save = 100;
 static uintmax_t next_mark;
 static struct strbuf new_data = STRBUF_INIT;
+static const char *path_prefix;
+static size_t path_prefix_len;
 
 static void write_branch_report(FILE *rpt, struct branch *b)
 {
@@ -1860,6 +1862,16 @@ static void load_branch(struct branch *b)
 	}
 }
 
+static const char *path_prefix_prepend(struct strbuf *sb, const char *p)
+{
+	if (p != sb->buf) {
+	    strbuf_reset(sb);
+	    strbuf_addstr(sb, p);
+	}
+	strbuf_insert(sb, 0, path_prefix, path_prefix_len);
+	return sb->buf;
+}
+
 static void file_change_m(struct branch *b)
 {
 	const char *p = command_buf.buf + 2;
@@ -1909,6 +1921,8 @@ static void file_change_m(struct branch *b)
 			die("Garbage after path in: %s", command_buf.buf);
 		p = uq.buf;
 	}
+	if (path_prefix)
+	    p = path_prefix_prepend(&uq, p);
 
 	if (S_ISGITLINK(mode)) {
 		if (inline_data)
@@ -1961,6 +1975,8 @@ static void file_change_d(struct branch *b)
 			die("Garbage after path in: %s", command_buf.buf);
 		p = uq.buf;
 	}
+	if (path_prefix)
+	    p = path_prefix_prepend(&uq, p);
 	tree_content_remove(&b->branch_tree, p, NULL);
 }
 
@@ -1984,6 +2000,8 @@ static void file_change_cr(struct branch *b, int rename)
 		strbuf_add(&s_uq, s, endp - s);
 	}
 	s = s_uq.buf;
+	if (path_prefix)
+	    s = path_prefix_prepend(&s_uq, s);
 
 	endp++;
 	if (!*endp)
@@ -1996,6 +2014,8 @@ static void file_change_cr(struct branch *b, int rename)
 			die("Garbage after dest in: %s", command_buf.buf);
 		d = d_uq.buf;
 	}
+	if (path_prefix)
+	    d = path_prefix_prepend(&d_uq, d);
 
 	memset(&leaf, 0, sizeof(leaf));
 	if (rename)
@@ -2523,6 +2543,10 @@ int main(int argc, const char **argv)
 			if (max_depth > MAX_DEPTH)
 				die("--depth cannot exceed %u", MAX_DEPTH);
 		}
+		else if (!prefixcmp(a, "--path-prefix=")) {
+			path_prefix = a + 14;
+			path_prefix_len = strlen(path_prefix);
+		}
 		else if (!prefixcmp(a, "--active-branches="))
 			max_active_branches = strtoul(a + 18, NULL, 0);
 		else if (!prefixcmp(a, "--import-marks="))
-- 
1.6.6.rc4.12.g269e7

```

## Sverre Rabbelier, 2009-12-29 14:06

Subject: Re: [PATCH] Add --path-prefix option to git-fast-import
Message-ID: <fabb9a1e0912290606ib1f2e46y1ddbae9aa68e5194@mail.gmail.com>
URL: https://gitlist.dev/e/fabb9a1e0912290606ib1f2e46y1ddbae9aa68e5194%40mail.gmail.com
In-Reply-To: <1262091083-25401-1-git-send-email-gisle.aas@it.uib.no>

```
Heya,

On Tue, Dec 29, 2009 at 06:51, Gisle Aas <gisle.aas@it.uib.no> wrote:
> +static const char *path_prefix_prepend(struct strbuf *sb, const char *p)
> +{
> +       if (p != sb->buf) {
> +           strbuf_reset(sb);
> +           strbuf_addstr(sb, p);
> +       }
> +       strbuf_insert(sb, 0, path_prefix, path_prefix_len);
> +       return sb->buf;
> +}
> +
>  static void file_change_m(struct branch *b)
>  {
>        const char *p = command_buf.buf + 2;
> @@ -1909,6 +1921,8 @@ static void file_change_m(struct branch *b)
>                        die("Garbage after path in: %s", command_buf.buf);
>                p = uq.buf;
>        }
> +       if (path_prefix)
> +           p = path_prefix_prepend(&uq, p);

You could reduce the size of this change by having path_prefix_prepend
check for path_prefix and just do nothing if it is not set.

-- 
Cheers,

Sverre Rabbelier

```

## Shawn O. Pearce, 2009-12-29 15:08

Subject: Re: [PATCH] Add --path-prefix option to git-fast-import
Message-ID: <20091229150844.GC6152@spearce.org>
URL: https://gitlist.dev/e/20091229150844.GC6152%40spearce.org
In-Reply-To: <1262091083-25401-1-git-send-email-gisle.aas@it.uib.no>

```
Gisle Aas <gisle.aas@it.uib.no> wrote:
> I found this useful when import multiple external repositories to be merged
> into a single git repo.  Not having the files be renamed during the merge
> made it easier to follow the history of the individual files.
> 
> Signed-off-by: Gisle Aas <gisle@aas.no>
> ---
>  Documentation/git-fast-import.txt |    6 ++++++
>  fast-import.c                     |   24 ++++++++++++++++++++++++
>  2 files changed, 30 insertions(+), 0 deletions(-)

Interesting.  Test cases?
 
> +static const char *path_prefix_prepend(struct strbuf *sb, const char *p)
> +{
> +	if (p != sb->buf) {
> +	    strbuf_reset(sb);
> +	    strbuf_addstr(sb, p);
> +	}

I'd be a bit happier about the change if you could check not only
that p != sb->buf, but that p is not within sb->buf + sb->alloc.

I can't remember if all of the cases below are safe such that
any time you call the function with a p that p isn't pointing to
something within the strbuf you are handing in.

-- 
Shawn.

```

## Gisle Aas, 2009-12-30 08:17

Subject: Re: [PATCH] Add --path-prefix option to git-fast-import
Message-ID: <6B75CF25-4EE4-4475-975D-BB1F9A5B8CC2@it.uib.no>
URL: https://gitlist.dev/e/6B75CF25-4EE4-4475-975D-BB1F9A5B8CC2%40it.uib.no
In-Reply-To: <fabb9a1e0912290606ib1f2e46y1ddbae9aa68e5194@mail.gmail.com>

```
On Dec 29, 2009, at 15:06, Sverre Rabbelier wrote:

> Heya,
> 
> On Tue, Dec 29, 2009 at 06:51, Gisle Aas <gisle.aas@it.uib.no> wrote:
>> +static const char *path_prefix_prepend(struct strbuf *sb, const char *p)
>> +{
>> +       if (p != sb->buf) {
>> +           strbuf_reset(sb);
>> +           strbuf_addstr(sb, p);
>> +       }
>> +       strbuf_insert(sb, 0, path_prefix, path_prefix_len);
>> +       return sb->buf;
>> +}
>> +
>>  static void file_change_m(struct branch *b)
>>  {
>>        const char *p = command_buf.buf + 2;
>> @@ -1909,6 +1921,8 @@ static void file_change_m(struct branch *b)
>>                        die("Garbage after path in: %s", command_buf.buf);
>>                p = uq.buf;
>>        }
>> +       if (path_prefix)
>> +           p = path_prefix_prepend(&uq, p);
> 
> You could reduce the size of this change by having path_prefix_prepend
> check for path_prefix and just do nothing if it is not set.

I felt the explict test was better style -- more obvious that nothing happens to p
when there is no path_prefix.

--Gisle
```
