git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 0/7] Foreign VCS support

From
PWPete Wyckoff <pw@padd.com>
Date
Jun 18, 2009, 11:53 UTC
Message-ID
<20090618115341.GC18449@arf.padd.com>
In-Reply-To
<alpine.LNX.2.00.0906161121590.2147@iabervon.org>
barkalow@iabervon.org wrote on Tue, 16 Jun 2009 13:29 -0400:
Show 22 quoted lines
> On Tue, 16 Jun 2009, Pete Wyckoff wrote:
> > //depot/path/to/project/dir/foo.txt
> > ... #1 change 555 branch on 2001/02/03 by x@y (ktext) 'Branch oldproj @444'
> > ... ... branch into //depot/path/to/branch1/dir/foo.txt#1
> > ... ... branch into //depot/path/to/branch2/dir/foo.txt#1
> > ... ... branch into //depot/path/to/branch3/dir/foo.txt#1
> > ... ... branch from //depot/oldproj/dir/main/foo.txt#1,#28
> >
> > The name and the "into" branches are in current use.  The last
> > "from" branch is the historic location from where everything was
> > moved recently.  Note the extra "main/" directory in there.  This
> > pattern is common throughout the historic depot format, but it
> > confuses get_related_file(), which complains and returns NULL.
> 
> So you've got a per-project mainline, which is integrated into branches. 
> My depot used to have mainlines, but eventually ditched them in favor of 
> only having branches, where 1.2 integrates into 1.3, and 1.3 integrates 
> into 1.4, and so on.
> 
> I'm surprised that the "main" is confusing get_related_file(); I'd think 
> that it would decide that //depot/oldproj/dir/main/foo.txt is foo.txt in 
> the codeline //depot/oldproj/dir/main/.

Because I'm trying to get it to fetch //depot/path/to/project so the base->name is "/dir/foo.txt" and the path is "//depot/oldproj/dir/main/foo.txt".

I hacked the code to look for the basename as well. It worked further, but added a codeline for every directory that had ever existed. There's way too many of these. And took forever, and stumbled on some odd codeline names that don't appear to be in the depot. These triggered a coredump that I also worked around.

Show 12 quoted lines
> > I don't particularly want to maintain this historic codeline
> > information, even if vcs-p4 could figure it out.  Is there a way
> > just to import the history of the file without having it be part of
> > a discovered codeline?  Perhaps always call get_codeline() and let
> > me use ignore_codelines to skip the oldproj ones by hand?  I do want
> > git to know about the "branch1" and similar, though, eventually.
> 
> In general, I just write my fetch rules so that the old codelines get 
> discovered and imported (so that the history is there), but then they 
> aren't fetched. That is, they're junk in refs/p4/* (which lets git keep 
> track of the fact that it imported them), but they don't end up in 
> refs/remotes/origin/*.

I ended up using a codelineformat regex to pick out just the recent branches, ignoring all the history. This did mostly work, like how the git-p4 script would do things. That's okay for me, as I didn't need the gobs of history anyway. I do need to handle cross-codeline integrates that happen in the future nicely, though. Maybe now I can relax the regexp and have it discover new codelines only if they appear in future integrates.

Here's the combined patch that I ended up with. Don't bother preserving this, just roll the good bits into your patches in the future.

If you make any nice changes, please send out the patches again. I would like to give it another spin once I have some recent integrates to play with.

		-- Pete
diff --git a/vcs-p4/vcs-p4.c b/vcs-p4/vcs-p4.c
index b1cff2f..dcbda78 100644
--- a/vcs-p4/vcs-p4.c
+++ b/vcs-p4/vcs-p4.c
@@ -96,6 +96,7 @@ static struct p4_codeline *get_codeline(struct p4_depot *depot, const char *path
 	struct p4_codeline **posn, *codeline;
 	int i;
 	unsigned char sha1[20];
+	char *refname;
 
 	if (codeline_regex && regexec(codeline_regex, path, 0, NULL, 0))
 		return NULL;
@@ -103,6 +104,12 @@ static struct p4_codeline *get_codeline(struct p4_depot *depot, const char *path
 	for (posn = &depot->codelines; *posn; posn = &(*posn)->next)
 		if (!strcmp(path, (*posn)->path))
 			return *posn;
+
+	refname = codeline_to_refname(path);
+	if (refname == NULL) {
+		fprintf(stderr, "%s: invalid codeline %s\n", __func__, path);
+		return NULL;
+	}
 	codeline = xcalloc(1, sizeof(*codeline));
 	codeline->depot = depot;
 	codeline->path = xstrdup(path);
@@ -111,7 +118,7 @@ static struct p4_codeline *get_codeline(struct p4_depot *depot, const char *path
 		if (!strcmp(path, ignore_codelines[i]))
 			codeline->ignore = 1;
 
-	codeline->refname = codeline_to_refname(path);
+	codeline->refname = refname;
 	if (!get_sha1(codeline->refname, sha1)) {
 		struct commit *commit = lookup_commit(sha1);
 		char *field;
@@ -129,6 +136,7 @@ static struct p4_codeline *get_codeline(struct p4_depot *depot, const char *path
 		}
 	}
 	*posn = codeline;
+	fprintf(stderr, "added codeline %s\n", codeline->path);
 	return codeline;
 }
 
@@ -210,27 +218,51 @@ static struct p4_file *get_file_by_full(struct p4_codeline *codeline,
 	return *posn;
 }
 
+#define dfprintf(fp, ...)
+/* #define dfprintf fprintf */
+
 static struct p4_file *get_related_file(struct p4_file *base, const char *path)
 {
-	int basenamelen = strlen(base->name);
-	int reldirlen = strlen(path) - basenamelen;
+	int basenamelen, reldirlen;
 	struct p4_codeline *codeline;
-	if (reldirlen > 0 && !strcmp(path + reldirlen, base->name)) {
+	const char *cp;
+
+	cp = base->name;
+strip:
+	basenamelen = strlen(cp);
+	reldirlen = strlen(path) - basenamelen;
+	dfprintf(stderr, "consider base %s in path %s\n", cp, path);
+	if (reldirlen > 0 && !strcmp(path + reldirlen, cp)) {
 		/* File with the same name in another codeline */
-		char *other = xstrndup(path, reldirlen);
-		//printf("# find %s in %s\n", path, other);
+		char *other;
+
+		/* else later filelog will add another / and fail */
+		if (path[reldirlen-1] == '/')
+			--reldirlen;
+		other = xstrndup(path, reldirlen);
+		dfprintf(stderr, "look for %s in %s\n", path, other);
 		codeline = get_codeline(base->codeline->depot, other);
-		free(other);
-		if (codeline)
+		if (codeline) {
+			dfprintf(stderr, "found %s in %s\n", path, other);
+			free(other);
 			return get_file_by_full(codeline, path);
-		return NULL;
+		} else {
+			free(other);
+		}
+	}
+	/* strip just the basename and try again to find it */
+	cp = strrchr(cp, '/');
+	if (cp) {
+		++cp;
+		goto strip;
 	}
+	dfprintf(stderr, "look for %s directly\n", path);
 	codeline = find_codeline(base->codeline->depot, path);
 	if (codeline) {
 		/* File with a different name in some known codeline */
 		return get_file_by_full(codeline, path);
 	}
-	fprintf(stderr, "Trying to identify %s\n", path);
+	dfprintf(stderr, "failed to find codeline for %s\n", path);
 	/* Not in any known codeline; need to recheck this after
 	 * discovering codelines completes.
 	 */
@@ -615,7 +647,7 @@ static void p4_filelog_cb(struct p4_filelog_data *data,
 			rev = strtoul(posn, &posn, 10);
 			if (*posn != ',')
 				break;
-			posn += 2;
+			posn += 2;  /* skip ,# */
 		} while (1);
 		if (from) {
 			struct p4_file *rel_file =
@@ -1168,11 +1200,6 @@ int main(int argc, const char **argv)
 		} else if (!strcmp(buf.buf, "list")) {
 			int i;
 
-			git_config(handle_config, remote);
-
-			ALLOC_GROW(env, env_nr + 1, env_alloc);
-			env[env_nr++] = NULL;
-
 			if (find_new_codelines) {
 				struct p4_codeline *codeline;
 				save_commit_buffer = 1;
Previous: Daniel BarkalowNext: Daniel Barkalow
Message 6 of 7 in “Foreign VCS support”
  1. 0/7 Foreign VCS supportDaniel Barkalow, May 27, 2009
  2. Pete WyckoffJun 15, 2009
  3. Daniel BarkalowJun 15, 2009
  4. Pete WyckoffJun 16, 2009
  5. Daniel BarkalowJun 16, 2009
  6. Pete WyckoffJun 18, 2009
  7. Daniel BarkalowJun 18, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.