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

Re: gitweb wishlist

From
DMDavid Mansfield <david@cobite.com>
Date
May 24, 2005, 20:03 UTC
Message-ID
<42938893.9010608@cobite.com>
In-Reply-To
<Pine.LNX.4.58.0505240911050.2307@ppc970.osdl.org>
Linus Torvalds wrote:
Show 18 quoted lines
> 
> On Tue, 24 May 2005, Linus Torvalds wrote:
> 
>>Fixing the branch handling shows that cvsps does some really strange
>>things with the newly added "Ancestor grpah". Here's one example:
> 
> 
> Ahh, looking at cvsps source, I think I see what's going on. 
> 
> It's deciding the "previous branch" by looking at what the previous branch 
> for the first individual file in the PatchSet was, which fails because in 
> this case, PatchSet 372 was changing "syslinux.doc", and Patchset 374 was 
> changing "syslinux.c", and thus the previous version of the individual 
> _files_ were both in the HEAD branch.
> 
> So it does look like I should just ignore the "Ancestor branch" 
> information if the new branch already existed.
> 

I've attached what I just committed. The previous 'show ancestor' patch needs to be reversed and this applied. It works for me on a half-dozen repos including syslinux.

You no longer should need to work around multiple reporting of the ancestor for a given branch, though it couldn't hurt.

I'm going to finish getting some of Thomas's patches in and make an actual release so people won't have to scour the lists.

David
---------------------
PatchSet 176 
Date: 2005/05/24 19:57:37
Author: david
Branch: HEAD
Tag: (none) 
Log:
show branch ancestry
Members: 
	cvsps.c:4.99->4.100 
	cvsps_types.h:4.9->4.10 
Index: cvsps/cvsps.c
diff -u cvsps/cvsps.c:4.99 cvsps/cvsps.c:4.100
--- cvsps/cvsps.c:4.99	Wed Jan 26 14:46:41 2005
+++ cvsps/cvsps.c	Tue May 24 15:57:37 2005
@@ -26,7 +26,7 @@
 #include "cap.h"
 #include "cvs_direct.h"
 
-RCSID("$Id: cvsps.c,v 4.99 2005/01/26 19:46:41 david Exp $");
+RCSID("$Id: cvsps.c,v 4.100 2005/05/24 19:57:37 david Exp $");
 
 #define CVS_LOG_BOUNDARY "----------------------------\n"
 #define CVS_FILE_BOUNDARY "=============================================================================\n"
@@ -75,6 +75,7 @@
 static int do_write_cache;
 static int statistics;
 static const char * test_log_file;
+static struct hash_table * branch_heads;
 
 /* settable via options */
 static int timestamp_fuzz_factor = 300;
@@ -101,6 +102,7 @@
 static int cvs_direct;
 static int compress;
 static char compress_arg[8];
+static int track_branch_ancestry;
 
 static void check_norc(int, char *[]);
 static int parse_args(int, char *[]);
@@ -112,7 +114,7 @@
 static void assign_pre_revision(PatchSetMember *, CvsFileRevision * rev);
 static void check_print_patch_set(PatchSet *);
 static void print_patch_set(PatchSet *);
-static void set_ps_id(const void *, const VISIT, const int);
+static void walk_all_ps(const void *, const VISIT, const int);
 static void show_ps_tree_node(const void *, const VISIT, const int);
 static int compare_patch_sets_bk(const void *, const void *);
 static int compare_patch_sets(const void *, const void *);
@@ -131,6 +133,7 @@
 static int check_rev_funk(PatchSet *, CvsFileRevision *);
 static CvsFileRevision * rev_follow_branch(CvsFileRevision *, const char *);
 static int before_tag(CvsFileRevision * rev, const char * tag);
+static void determine_branch_ancestor(PatchSet * ps, PatchSet * head_ps);
 
 int main(int argc, char *argv[])
 {
@@ -164,6 +167,7 @@
 
     file_hash = create_hash_table(1023);
     global_symbols = create_hash_table(111);
+    branch_heads = create_hash_table(1023);
 
     /* this parses some of the CVS/ files, and initializes
      * the repository_path and other variables 
@@ -197,7 +201,7 @@
     }
 
     ps_counter = 0;
-    twalk(ps_tree_bytime, set_ps_id);
+    twalk(ps_tree_bytime, walk_all_ps);
 
     resolve_global_symbols();
 
@@ -536,7 +540,7 @@
     debug(DEBUG_APPERROR, "             [--test-log <captured cvs log file>] [--bkcvs]");
     debug(DEBUG_APPERROR, "             [--no-rlog] [--diff-opts <option string>] [--cvs-direct]");
     debug(DEBUG_APPERROR, "             [--debuglvl <bitmask>] [-Z <compression>] [--root <cvsroot>]");
-    debug(DEBUG_APPERROR, "             [<repository>] [-q]");
+    debug(DEBUG_APPERROR, "             [-q] [-A] [<repository>]");
     debug(DEBUG_APPERROR, "");
     debug(DEBUG_APPERROR, "Where:");
     debug(DEBUG_APPERROR, "  -h display this informative message");
@@ -569,6 +573,7 @@
     debug(DEBUG_APPERROR, "  -Z <compression> A value 1-9 which specifies amount of compression");
     debug(DEBUG_APPERROR, "  --root <cvsroot> specify cvsroot.  overrides env. and working directory");
     debug(DEBUG_APPERROR, "  -q be quiet about warnings");
+    debug(DEBUG_APPERROR, "  -A track and report branch ancestry");
     debug(DEBUG_APPERROR, "  <repository> apply cvsps to repository.  overrides working directory");
     debug(DEBUG_APPERROR, "\ncvsps version %s\n", VERSION);
 
@@ -867,6 +872,13 @@
 	    continue;
 	}
 
+	if (strcmp(argv[i], "-A") == 0)
+	{
+	    track_branch_ancestry = 1;
+	    i++;
+	    continue;
+	}
+
 	if (argv[i][0] == '-')
 	    return usage("invalid argument", argv[i]);
 	
@@ -1398,6 +1410,8 @@
 	   tm->tm_hour, tm->tm_min, tm->tm_sec);
     printf("Author: %s\n", ps->author);
     printf("Branch: %s\n", ps->branch);
+    if (ps->ancestor_branch)
+	printf("Ancestor branch: %s\n", ps->ancestor_branch);
     printf("Tag: %s %s\n", ps->tag ? ps->tag : "(none)", tag_flag_descr[ps->tag_flags]);
     printf("Log:\n%s\n", ps->descr);
     printf("Members: \n");
@@ -1425,7 +1439,10 @@
     printf("\n");
 }
 
-static void set_ps_id(const void * nodep, const VISIT which, const int depth)
+/* walk all the patchsets to assign monotonic psid, 
+ * and to establish  branch ancestry
+ */
+static void walk_all_ps(const void * nodep, const VISIT which, const int depth)
 {
     PatchSet * ps;
 
@@ -1442,6 +1459,18 @@
 	{
 	    ps_counter++;
 	    ps->psid = ps_counter;
+
+	    if (track_branch_ancestry && strcmp(ps->branch, "HEAD") != 0)
+	    {
+		PatchSet * head_ps = (PatchSet*)get_hash_object(branch_heads, ps->branch);
+		if (!head_ps) 
+		{
+		    head_ps = ps;
+		    put_hash_object(branch_heads, ps->branch, head_ps);
+		}
+
+		determine_branch_ancestor(ps, head_ps);
+	    }
 	}
 	else
 	{
@@ -1912,6 +1941,7 @@
 	ps->tag_flags = 0;
 	ps->branch_add = 0;
 	ps->funk_factor = 0;
+	ps->ancestor_branch = NULL;
     }
 
     return ps;
@@ -2235,21 +2265,25 @@
     return 0;
 }
 
-/*
- * When importing vendor sources, (apparently people do this)
- * the code is added on a 'vendor' branch, which, for some reason
- * doesn't use the magic-branch-tag format.  Try to detect that now
- */
-static int is_vendor_branch(const char * rev)
+static int count_dots(const char * p)
 {
     int dots = 0;
-    const char *p = rev;
 
     while (*p)
 	if (*p++ == '.')
 	    dots++;
 
-    return !(dots&1);
+    return dots;
+}
+
+/*
+ * When importing vendor sources, (apparently people do this)
+ * the code is added on a 'vendor' branch, which, for some reason
+ * doesn't use the magic-branch-tag format.  Try to detect that now
+ */
+static int is_vendor_branch(const char * rev)
+{
+    return !(count_dots(rev)&1);
 }
 
 void patch_set_add_member(PatchSet * ps, PatchSetMember * psm)
@@ -2395,5 +2429,69 @@
 	    break;
 	}
 	i++;
+    }
+}
+
+static void determine_branch_ancestor(PatchSet * ps, PatchSet * head_ps)
+{
+    struct list_head * next;
+    CvsFileRevision * rev;
+
+    /* PatchSet 1 has no ancestor */
+    if (ps->psid == 1)
+	return;
+
+    /* HEAD branch patchsets have no ancestry, but callers should know that */
+    if (strcmp(ps->branch, "HEAD") == 0)
+    {
+	debug(DEBUG_APPMSG1, "WARNING: no branch ancestry for HEAD");
+	return;
+    }
+
+    for (next = ps->members.next; next != &ps->members; next = next->next) 
+    {
+	PatchSetMember * psm = list_entry(next, PatchSetMember, link);
+	rev = psm->pre_rev;
+	int d1, d2;
+
+	/* the reason this is at all complicated has to do with a 
+	 * branch off of a branch.  it is possible (and indeed 
+	 * likely) that some file would not have been modified 
+	 * from the initial branch point to the branch-off-branch 
+	 * point, and therefore the branch-off-branch point is 
+	 * really branch-off-HEAD for that specific member (file).  
+	 * in that case, rev->branch will say HEAD but we want 
+	 * to know the symbolic name of the first branch
+	 * so we continue to look member after member until we find
+	 * the 'deepest' branching.  deepest can actually be determined
+	 * by considering the revision currently indicated by 
+	 * ps->ancestor_branch (by symbolic lookup) and rev->rev. the 
+	 * one with more dots wins
+	 *
+	 * also, the first commit in which a branch-off-branch is 
+	 * mentioned may ONLY modify files never committed since
+	 * original branch-off-HEAD was created, so we have to keep
+	 * checking, ps after ps to be sure to get the deepest ancestor
+	 *
+	 * note: rev is the pre-commit revision, not the post-commit
+	 */
+	if (!head_ps->ancestor_branch)
+	    d1 = 0;
+	else if (strcmp(ps->branch, rev->branch) == 0)
+	    continue;
+	else if (strcmp(head_ps->ancestor_branch, "HEAD") == 0)
+	    d1 = 1;
+	else {
+	    /* branch_rev may not exist if the file was added on this branch for example */
+	    const char * branch_rev = (char *)get_hash_object(rev->file->branches_sym, head_ps->ancestor_branch);
+	    d1 = branch_rev ? count_dots(branch_rev) : 1;
+	}
+
+	d2 = count_dots(rev->rev);
+	
+	if (d2 > d1)
+	    head_ps->ancestor_branch = rev->branch;
+
+ 	//printf("-----> %d ancestry %s %s %s\n", ps->psid, ps->branch, head_ps->ancestor_branch, rev->file->filename);
     }
 }
Index: cvsps/cvsps_types.h
diff -u cvsps/cvsps_types.h:4.9 cvsps/cvsps_types.h:4.10
--- cvsps/cvsps_types.h:4.9	Mon Mar 31 18:06:18 2003
+++ cvsps/cvsps_types.h	Tue May 24 15:57:37 2005
@@ -110,6 +110,7 @@
     char *tag;
     int tag_flags;
     char *branch;
+    char *ancestor_branch;
     struct list_head members;
     /*
      * A 'branch add' patch set is a bogus patch set created automatically
Previous: David MansfieldNext: David Mansfield
Message 49 of 102 in “gitweb wishlist”
  1. Petr BaudisMay 11, 2005
  2. YOSHIFUJI Hideaki / 吉藤英明May 11, 2005
  3. Petr BaudisMay 11, 2005
  4. Kay SieversMay 11, 2005
  5. Jan-Benedict GlawMay 11, 2005
  6. Kay SieversMay 14, 2005
  7. Junio C HamanoMay 12, 2005
  8. Kay SieversMay 12, 2005
  9. Junio C HamanoMay 12, 2005
  10. Junio C HamanoJun 4, 2005
  11. Jonas FonsecaMay 13, 2005
  12. Kay SieversMay 14, 2005
  13. Kay SieversMay 14, 2005
  14. Jonas FonsecaMay 14, 2005
  15. Kay SieversMay 18, 2005
  16. Petr BaudisMay 18, 2005
  17. Linus TorvaldsMay 20, 2005
  18. Junio C HamanoMay 20, 2005
  19. Linus TorvaldsMay 20, 2005
  20. Kay SieversMay 20, 2005
  21. Linus TorvaldsMay 20, 2005
  22. Linus TorvaldsMay 20, 2005
  23. Kay SieversMay 20, 2005
  24. Thomas GlanzmannMay 20, 2005
  25. Linus TorvaldsMay 20, 2005
  26. Linus TorvaldsMay 20, 2005
  27. H. Peter AnvinMay 20, 2005
  28. Linus TorvaldsMay 20, 2005
  29. H. Peter AnvinMay 20, 2005
  30. Thomas GlanzmannMay 20, 2005
  31. Kay SieversMay 20, 2005
  32. H. Peter AnvinMay 20, 2005
  33. Linus TorvaldsMay 20, 2005
  34. Kay SieversMay 20, 2005
  35. Kay SieversMay 20, 2005
  36. Matthias UrlichsMay 21, 2005
  37. Kay SieversMay 21, 2005
  38. Linus TorvaldsMay 21, 2005
  39. cvs->git (was Re: gitweb wishlist)Matthias Urlichs, May 21, 2005
  40. David MansfieldMay 24, 2005
  41. H. Peter AnvinMay 24, 2005
  42. David MansfieldMay 24, 2005
  43. H. Peter AnvinMay 24, 2005
  44. Linus TorvaldsMay 24, 2005
  45. Linus TorvaldsMay 24, 2005
  46. Linus TorvaldsMay 24, 2005
  47. Linus TorvaldsMay 24, 2005
  48. David MansfieldMay 24, 2005
  49. David MansfieldMay 24, 2005
  50. David MansfieldMay 24, 2005
  51. David MansfieldMay 24, 2005
  52. Linus TorvaldsMay 24, 2005
  53. H. Peter AnvinMay 24, 2005
  54. David MansfieldMay 24, 2005
  55. Thomas GlanzmannMay 24, 2005
  56. Linus TorvaldsMay 24, 2005
  57. Linus TorvaldsMay 24, 2005
  58. Linus TorvaldsMay 24, 2005
  59. Thomas GlanzmannMay 24, 2005
  60. Linus TorvaldsMay 24, 2005
  61. Edgar ToernigMay 24, 2005
  62. Linus TorvaldsMay 24, 2005
  63. Junio C HamanoMay 25, 2005
  64. Linus TorvaldsMay 25, 2005
  65. Junio C HamanoMay 25, 2005
  66. David MansfieldMay 24, 2005
  67. Thomas GlanzmannMay 24, 2005
  68. Linus TorvaldsMay 24, 2005
  69. Linus TorvaldsMay 24, 2005
  70. David MansfieldMay 24, 2005
  71. Linus TorvaldsMay 24, 2005
  72. Thomas GlanzmannMay 24, 2005
  73. Linus TorvaldsMay 24, 2005
  74. Thomas GlanzmannMay 24, 2005
  75. Linus TorvaldsMay 24, 2005
  76. David MansfieldMay 24, 2005
  77. Linus TorvaldsMay 24, 2005
  78. H. Peter AnvinMay 24, 2005
  79. Thomas GlanzmannMay 24, 2005
  80. Thomas GlanzmannMay 24, 2005
  81. Kay SieversMay 24, 2005
  82. Linus TorvaldsMay 24, 2005
  83. Junio C HamanoMay 25, 2005
  84. Linus TorvaldsMay 25, 2005
  85. Junio C HamanoMay 25, 2005
  86. Kay SieversMay 25, 2005
  87. David GreavesMay 25, 2005
  88. Junio C HamanoMay 25, 2005
  89. David GreavesMay 25, 2005
  90. Kay SieversMay 25, 2005
  91. Kay SieversMay 25, 2005
  92. Junio C HamanoMay 25, 2005
  93. Junio C HamanoMay 25, 2005
  94. Linus TorvaldsMay 24, 2005
  95. Thomas GlanzmannMay 24, 2005
  96. Linus TorvaldsMay 24, 2005
  97. Thomas GlanzmannMay 24, 2005
  98. Junio C HamanoMay 24, 2005
  99. Junio C HamanoMay 24, 2005
  100. Martin LanghoffMay 24, 2005
  101. Thomas GlanzmannMay 24, 2005
  102. David MansfieldMay 26, 2005

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.