commit-reach: move ref_newer from remote.c
There are several commit walks in the codebase. Group them together into a new commit-reach.c file and corresponding header. After we group these walks into one place, we can reduce duplicate logic by calling equivalent methods. The ref_newer() method is used by 'git push -f' to check if a force-push is necessary. By making the method public, we make it possible to test the method directly without setting up an envieronment where a 'git push' call makes sense. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Jul 20, 2018 at 16:33 UTC
1d614d41e5fc030bc2f2799a58791aa912f78378
5 files changed
+57
-51
builtin/remote.c
+1
@@ -10,6 +10,7 @@
10
#include "refspec.h"
11
#include "object-store.h"
12
#include "argv-array.h"
13
+#include "commit-reach.h"
14
15
static const char * const builtin_remote_usage[] = {
16
N_("git remote [-v | --verbose]"),
commit-reach.c
+54
-1
@@ -1,6 +1,10 @@
1
#include "cache.h"
2
-#include "prio-queue.h"
2
#include "commit.h"
3
+#include "decorate.h"
4
+#include "prio-queue.h"
5
+#include "tree.h"
6
+#include "revision.h"
7
+#include "tag.h"
8
#include "commit-reach.h"
9
10
/* Remember to update object flag allocation in object.h */
@@ -358,3 +362,52 @@ void reduce_heads_replace(struct commit_list **heads)
362
free_commit_list(*heads);
363
*heads = result;
364
}
365
+
366
+static void unmark_and_free(struct commit_list *list, unsigned int mark)
367
+{
368
+ while (list) {
369
+ struct commit *commit = pop_commit(&list);
370
+ commit->object.flags &= ~mark;
371
+ }
372
+}
373
+
374
+int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
375
+{
376
+ struct object *o;
377
+ struct commit *old_commit, *new_commit;
378
+ struct commit_list *list, *used;
379
+ int found = 0;
380
+
381
+ /*
382
+ * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
383
+ * old_commit. Otherwise we require --force.
384
+ */
385
+ o = deref_tag(the_repository, parse_object(the_repository, old_oid),
386
+ NULL, 0);
387
+ if (!o || o->type != OBJ_COMMIT)
388
+ return 0;
389
+ old_commit = (struct commit *) o;
390
+
391
+ o = deref_tag(the_repository, parse_object(the_repository, new_oid),
392
+ NULL, 0);
393
+ if (!o || o->type != OBJ_COMMIT)
394
+ return 0;
395
+ new_commit = (struct commit *) o;
396
+
397
+ if (parse_commit(new_commit) < 0)
398
+ return 0;
399
+
400
+ used = list = NULL;
401
+ commit_list_insert(new_commit, &list);
402
+ while (list) {
403
+ new_commit = pop_most_recent_commit(&list, TMP_MARK);
404
+ commit_list_insert(new_commit, &used);
405
+ if (new_commit == old_commit) {
406
+ found = 1;
407
+ break;
408
+ }
409
+ }
410
+ unmark_and_free(list, TMP_MARK);
411
+ unmark_and_free(used, TMP_MARK);
412
+ return found;
413
+}
commit-reach.h
+2
@@ -39,4 +39,6 @@ struct commit_list *reduce_heads(struct commit_list *heads);
39
*/
40
void reduce_heads_replace(struct commit_list **heads);
41
42
+int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid);
43
+
44
#endif
remote.c
-49
@@ -1784,55 +1784,6 @@ int resolve_remote_symref(struct ref *ref, struct ref *list)
1784
return 1;
1785
}
1786
1787
-static void unmark_and_free(struct commit_list *list, unsigned int mark)
1788
-{
1789
- while (list) {
1790
- struct commit *commit = pop_commit(&list);
1791
- commit->object.flags &= ~mark;
1792
- }
1793
-}
1794
-
1795
-int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
1796
-{
1797
- struct object *o;
1798
- struct commit *old_commit, *new_commit;
1799
- struct commit_list *list, *used;
1800
- int found = 0;
1801
-
1802
- /*
1803
- * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
1804
- * old_commit. Otherwise we require --force.
1805
- */
1806
- o = deref_tag(the_repository, parse_object(the_repository, old_oid),
1807
- NULL, 0);
1808
- if (!o || o->type != OBJ_COMMIT)
1809
- return 0;
1810
- old_commit = (struct commit *) o;
1811
-
1812
- o = deref_tag(the_repository, parse_object(the_repository, new_oid),
1813
- NULL, 0);
1814
- if (!o || o->type != OBJ_COMMIT)
1815
- return 0;
1816
- new_commit = (struct commit *) o;
1817
-
1818
- if (parse_commit(new_commit) < 0)
1819
- return 0;
1820
-
1821
- used = list = NULL;
1822
- commit_list_insert(new_commit, &list);
1823
- while (list) {
1824
- new_commit = pop_most_recent_commit(&list, TMP_MARK);
1825
- commit_list_insert(new_commit, &used);
1826
- if (new_commit == old_commit) {
1827
- found = 1;
1828
- break;
1829
- }
1830
- }
1831
- unmark_and_free(list, TMP_MARK);
1832
- unmark_and_free(used, TMP_MARK);
1833
- return found;
1834
-}
1835
-
1787
/*
1788
* Lookup the upstream branch for the given branch and if present, optionally
1789
* compute the commit ahead/behind values for the pair.
remote.h
-1
@@ -149,7 +149,6 @@ extern struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
149
const struct string_list *server_options);
150
151
int resolve_remote_symref(struct ref *ref, struct ref *list);
152
-int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid);
152
153
/*
154
* Remove and free all but the first of any entries in the input list