rev-list: omit duplicated parents.
Showing the same parent more than once for a commit does not make much sense downstream, so stop it. This can happen with an incorrectly made merge commit that merges the same parent twice, but can happen in an otherwise sane development history while squishing the history by taking into account only commits that touch specified paths. For example, $ git rev-list --max-count=1 --parentsmaintaddafaf-- rev-list.c would have to show this commit ancestry graph: .---o---. / \ .---*---o---. /93b74bc\ ---*---o---o-----o---o-----oaddafafd8f6b34\ / .---o---o---. \ / .---*---.3815f42where 5 independent development tracks, only two of which have changes in the specified paths since they forked. The last change for the other three development tracks was done by the same commit before they forked, and we were showing that three times. Signed-off-by: Junio C Hamano <junkio@cox.net>
							parent
							
								
									2d49711512
								
							
						
					
					
						commit
						884944239f
					
				
							
								
								
									
										15
									
								
								rev-list.c
								
								
								
								
							
							
						
						
									
										15
									
								
								rev-list.c
								
								
								
								
							|  | @ -12,6 +12,7 @@ | |||
| #define COUNTED		(1u << 2) | ||||
| #define SHOWN		(1u << 3) | ||||
| #define TREECHANGE	(1u << 4) | ||||
| #define TMP_MARK	(1u << 5) /* for isolated cases; clean after use */ | ||||
|  | ||||
| static const char rev_list_usage[] = | ||||
| "git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n" | ||||
|  | @ -72,9 +73,21 @@ static void show_commit(struct commit *commit) | |||
| 	if (show_parents) { | ||||
| 		struct commit_list *parents = commit->parents; | ||||
| 		while (parents) { | ||||
| 			printf(" %s", sha1_to_hex(parents->item->object.sha1)); | ||||
| 			struct object *o = &(parents->item->object); | ||||
| 			parents = parents->next; | ||||
| 			if (o->flags & TMP_MARK) | ||||
| 				continue; | ||||
| 			printf(" %s", sha1_to_hex(o->sha1)); | ||||
| 			o->flags |= TMP_MARK; | ||||
| 		} | ||||
| 		/* TMP_MARK is a general purpose flag that can | ||||
| 		 * be used locally, but the user should clean | ||||
| 		 * things up after it is done with them. | ||||
| 		 */ | ||||
| 		for (parents = commit->parents; | ||||
| 		     parents; | ||||
| 		     parents = parents->next) | ||||
| 			parents->item->object.flags &= ~TMP_MARK; | ||||
| 	} | ||||
| 	if (commit_format == CMIT_FMT_ONELINE) | ||||
| 		putchar(' '); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano