@matheusbsbs / matheus-bagliano / commits / 753dc384dc
Fork 0

git svn: handle SVN merges from revisions past the tip of the branch

When recording the revisions that it has merged, SVN sets the top revision to be the latest revision in the repository, which is not necessarily a revision on the branch that is being merged from. When it is not on the branch, git-svn fails to add the extra parent to represent the merge because it relies on finding the commit on the branch that corresponds to the top of the SVN merge range. In order to correctly handle this case, we look for the maximum revision less than or equal to the top of the SVN merge range that is actually on the branch being merged from. [ew: This includes the following (squashed) commit to prevent errors during bisect:] Author: Toby Allsopp <toby.allsopp@navman.co.nz> Date: Fri Nov 13 09:48:39 2009 +1300 git-svn: add (failing) test for SVN 1.5+ merge with intervening commit This test exposes a bug in git-svn's handling of SVN 1.5+ mergeinfo properties. The problematic case is when there is some commit on an unrelated branch after the last commit on the merged-from branch. When SVN records the mergeinfo property, it records the latest revision in the whole repository, which, in the problematic case, is not on the branch it is merging from. To trigger the git-svn bug, we modify t9151 to include two SVN merges, the second of which has an intervening commit. The SVN dump was generated using SVN 1.6.6 (on Debian squeeze amd64). Signed-off-by: Toby Allsopp <toby.allsopp@navman.co.nz> Acked-by: Eric Wong <normalperson@yhbt.net>

Toby Allsopp committed Nov 14, 2009 at 13:26 UTC 753dc384dc2c4ab3e1049f695425cebf41ff7e6b
4 files changed +371 -60
git-svn.perl
+5 -2
@@ -2950,8 +2950,11 @@ sub find_extra_svn_parents {
2950 my $bottom_commit =
2951 $gs->rev_map_get($bottom, $self->ra_uuid) ||
2952 $gs->rev_map_get($bottom+1, $self->ra_uuid);
2953 - my $top_commit =
2954 - $gs->rev_map_get($top, $self->ra_uuid);
2953 + my $top_commit;
2954 + for (; !$top_commit && $top >= $bottom; --$top) {
2955 + $top_commit =
2956 + $gs->rev_map_get($top, $self->ra_uuid);
2957 + }
2958
2959 unless ($top_commit and $bottom_commit) {
2960 warn "W:unknown path/rev in svn:mergeinfo "
t/t9151-svn-mergeinfo.sh
+5 -1
@@ -15,7 +15,11 @@ test_expect_success 'load svn dump' "
15 git svn fetch --all
16 "
17
18 -test_expect_success 'svn merges were represented coming in' "
18 +test_expect_success 'represent svn merges without intervening commits' "
19 + [ `git cat-file commit HEAD^1 | grep parent | wc -l` -eq 2 ]
20 + "
21 +
22 +test_expect_success 'represent svn merges with intervening commits' "
23 [ `git cat-file commit HEAD | grep parent | wc -l` -eq 2 ]
24 "
25
t/t9151/make-svnmerge-dump
+31 -1
@@ -28,6 +28,10 @@ svn cp trunk branches/left
28
29 echo "Committing BRANCH POINT"
30 svn commit -m "make left branch"
31 +svn cp trunk branches/right
32 +
33 +echo "Committing other BRANCH POINT"
34 +svn commit -m "make right branch"
35 cd branches/left/
36
37 #$sm init
@@ -64,7 +68,33 @@ git cat-file blob b51ad431:Makefile > Makefile
68
69 svn resolved Makefile
70
67 -svn commit -m "Merge trunk"
71 +svn commit -m "Merge trunk 1"
72 +
73 +# create commits on both branches
74 +
75 +cd ../branches/left
76 +git cat-file blob ff5ebe39:Makefile > Makefile
77 +echo "Committing BRANCH UPDATE 4"
78 +svn commit -m "left update 4"
79 +
80 +cd ../right
81 +git cat-file blob b5039db6:Makefile > Makefile
82 +echo "Committing other BRANCH UPDATE 1"
83 +svn commit -m "right update 1"
84 +
85 +# merge to trun again
86 +
87 +cd ../..
88 +svn update
89 +cd trunk
90 +
91 +svn merge ../branches/left --accept postpone
92 +
93 +git cat-file blob b51ad431:Makefile > Makefile
94 +
95 +svn resolved Makefile
96 +
97 +svn commit -m "Merge trunk 2"
98
99 cd ../..
100
t/t9151/svn-mergeinfo.dump
+330 -56
@@ -1,6 +1,6 @@
1 SVN-fs-dump-format-version: 2
2
3 -UUID: 1ce241d1-ba54-4eb9-bded-03057fe48a33
3 +UUID: 1530d5a2-a1dc-4438-8ad5-d95e96db8945
4
5 Revision-number: 0
6 Prop-content-length: 56
@@ -9,12 +9,12 @@ Content-length: 56
9 K 8
10 svn:date
11 V 27
12 -2009-10-20T01:33:37.692723Z
12 +2009-11-12T20:29:38.812226Z
13 PROPS-END
14
15 Revision-number: 1
16 -Prop-content-length: 123
17 -Content-length: 123
16 +Prop-content-length: 127
17 +Content-length: 127
18
19 K 7
20 svn:log
@@ -22,12 +22,12 @@ V 24
22 Setup trunk and branches
23 K 10
24 svn:author
25 -V 4
26 -samv
25 +V 8
26 +tallsopp
27 K 8
28 svn:date
29 V 27
30 -2009-10-20T01:33:38.159933Z
30 +2009-11-12T20:29:39.045856Z
31 PROPS-END
32
33 Node-path: branches
@@ -49,8 +49,8 @@ PROPS-END
49
50
51 Revision-number: 2
52 -Prop-content-length: 106
53 -Content-length: 106
52 +Prop-content-length: 110
53 +Content-length: 110
54
55 K 7
56 svn:log
@@ -58,12 +58,12 @@ V 8
58 ancestor
59 K 10
60 svn:author
61 -V 4
62 -samv
61 +V 8
62 +tallsopp
63 K 8
64 svn:date
65 V 27
66 -2009-10-20T01:33:39.160059Z
66 +2009-11-12T20:29:40.079587Z
67 PROPS-END
68
69 Node-path: trunk/Makefile
@@ -72,6 +72,7 @@ Node-action: add
72 Prop-content-length: 10
73 Text-content-length: 2401
74 Text-content-md5: bfd8ff778d1492dc6758567373176a89
75 +Text-content-sha1: 103205ce331f7d64086dba497574734f78439590
76 Content-length: 2411
77
78 PROPS-END
@@ -155,8 +156,8 @@ backup: clean
156
157
158 Revision-number: 3
158 -Prop-content-length: 115
159 -Content-length: 115
159 +Prop-content-length: 119
160 +Content-length: 119
161
162 K 7
163 svn:log
@@ -164,12 +165,12 @@ V 16
165 make left branch
166 K 10
167 svn:author
167 -V 4
168 -samv
168 +V 8
169 +tallsopp
170 K 8
171 svn:date
172 V 27
172 -2009-10-20T01:33:41.148192Z
173 +2009-11-12T20:29:42.084439Z
174 PROPS-END
175
176 Node-path: branches/left
@@ -177,27 +178,54 @@ Node-kind: dir
178 Node-action: add
179 Node-copyfrom-rev: 1
180 Node-copyfrom-path: trunk
180 -Prop-content-length: 34
181 -Content-length: 34
181
183 -K 13
184 -svn:mergeinfo
185 -V 0
182
183 +Node-path: branches/left/Makefile
184 +Node-kind: file
185 +Node-action: add
186 +Node-copyfrom-rev: 2
187 +Node-copyfrom-path: trunk/Makefile
188 +Text-copy-source-md5: bfd8ff778d1492dc6758567373176a89
189 +Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590
190 +
191 +
192 +Revision-number: 4
193 +Prop-content-length: 120
194 +Content-length: 120
195 +
196 +K 7
197 +svn:log
198 +V 17
199 +make right branch
200 +K 10
201 +svn:author
202 +V 8
203 +tallsopp
204 +K 8
205 +svn:date
206 +V 27
207 +2009-11-12T20:29:44.065452Z
208 PROPS-END
209
210 +Node-path: branches/right
211 +Node-kind: dir
212 +Node-action: add
213 +Node-copyfrom-rev: 1
214 +Node-copyfrom-path: trunk
215 +
216
190 -Node-path: branches/left/Makefile
217 +Node-path: branches/right/Makefile
218 Node-kind: file
219 Node-action: add
220 Node-copyfrom-rev: 2
221 Node-copyfrom-path: trunk/Makefile
222 Text-copy-source-md5: bfd8ff778d1492dc6758567373176a89
223 +Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590
224
225
198 -Revision-number: 4
199 -Prop-content-length: 112
200 -Content-length: 112
226 +Revision-number: 5
227 +Prop-content-length: 116
228 +Content-length: 116
229
230 K 7
231 svn:log
@@ -205,12 +233,12 @@ V 13
233 left update 1
234 K 10
235 svn:author
208 -V 4
209 -samv
236 +V 8
237 +tallsopp
238 K 8
239 svn:date
240 V 27
213 -2009-10-20T01:33:42.148773Z
241 +2009-11-12T20:29:45.066262Z
242 PROPS-END
243
244 Node-path: branches/left/Makefile
@@ -218,6 +246,7 @@ Node-kind: file
246 Node-action: change
247 Text-content-length: 2465
248 Text-content-md5: 16e38d9753b061731650561ce01b1195
249 +Text-content-sha1: 36da4b84ea9b64218ab48171dfc5c48ae025f38b
250 Content-length: 2465
251
252 # -DCOLLISION_CHECK if you believe that SHA1's
@@ -299,9 +328,9 @@ backup: clean
328 cd .. ; tar czvf dircache.tar.gz dir-cache
329
330
302 -Revision-number: 5
303 -Prop-content-length: 111
304 -Content-length: 111
331 +Revision-number: 6
332 +Prop-content-length: 115
333 +Content-length: 115
334
335 K 7
336 svn:log
@@ -309,12 +338,12 @@ V 12
338 trunk update
339 K 10
340 svn:author
312 -V 4
313 -samv
341 +V 8
342 +tallsopp
343 K 8
344 svn:date
345 V 27
317 -2009-10-20T01:33:43.159959Z
346 +2009-11-12T20:29:46.278498Z
347 PROPS-END
348
349 Node-path: trunk/Makefile
@@ -322,6 +351,7 @@ Node-kind: file
351 Node-action: change
352 Text-content-length: 2521
353 Text-content-md5: 0668418a621333f4aa8b6632cd63e2a0
354 +Text-content-sha1: 4f29afd038e52f45acb5ef8c41acfc70062a741a
355 Content-length: 2521
356
357 # -DCOLLISION_CHECK if you believe that SHA1's
@@ -406,9 +436,9 @@ backup: clean
436 cd .. ; tar czvf dircache.tar.gz dir-cache
437
438
409 -Revision-number: 6
410 -Prop-content-length: 112
411 -Content-length: 112
439 +Revision-number: 7
440 +Prop-content-length: 116
441 +Content-length: 116
442
443 K 7
444 svn:log
@@ -416,12 +446,12 @@ V 13
446 left update 2
447 K 10
448 svn:author
419 -V 4
420 -samv
449 +V 8
450 +tallsopp
451 K 8
452 svn:date
453 V 27
424 -2009-10-20T01:33:44.164175Z
454 +2009-11-12T20:29:47.069090Z
455 PROPS-END
456
457 Node-path: branches/left/Makefile
@@ -429,6 +459,7 @@ Node-kind: file
459 Node-action: change
460 Text-content-length: 2529
461 Text-content-md5: f6b197cc3f2e89a83e545d4bb003de73
462 +Text-content-sha1: 2f656677cfec0bceec85e53036ffb63e25126f8e
463 Content-length: 2529
464
465 # -DCOLLISION_CHECK if you believe that SHA1's
@@ -510,9 +541,9 @@ backup: clean
541 cd .. ; tar czvf dircache.tar.gz dir-cache
542
543
513 -Revision-number: 7
514 -Prop-content-length: 112
515 -Content-length: 112
544 +Revision-number: 8
545 +Prop-content-length: 116
546 +Content-length: 116
547
548 K 7
549 svn:log
@@ -520,12 +551,12 @@ V 13
551 left update 3
552 K 10
553 svn:author
523 -V 4
524 -samv
554 +V 8
555 +tallsopp
556 K 8
557 svn:date
558 V 27
528 -2009-10-20T01:33:45.144214Z
559 +2009-11-12T20:29:48.053835Z
560 PROPS-END
561
562 Node-path: branches/left/Makefile
@@ -533,6 +564,7 @@ Node-kind: file
564 Node-action: change
565 Text-content-length: 2593
566 Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba
567 +Text-content-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10
568 Content-length: 2593
569
570 # -DCOLLISION_CHECK if you believe that SHA1's
@@ -614,22 +646,22 @@ backup: clean
646 cd .. ; tar czvf dircache.tar.gz dir-cache
647
648
617 -Revision-number: 8
618 -Prop-content-length: 110
619 -Content-length: 110
649 +Revision-number: 9
650 +Prop-content-length: 116
651 +Content-length: 116
652
653 K 7
654 svn:log
623 -V 11
624 -Merge trunk
655 +V 13
656 +Merge trunk 1
657 K 10
658 svn:author
627 -V 4
628 -samv
659 +V 8
660 +tallsopp
661 K 8
662 svn:date
663 V 27
632 -2009-10-20T01:33:48.176135Z
664 +2009-11-12T20:29:51.098306Z
665 PROPS-END
666
667 Node-path: trunk
@@ -641,7 +673,7 @@ Content-length: 53
673 K 13
674 svn:mergeinfo
675 V 18
644 -/branches/left:2-7
676 +/branches/left:2-8
677 PROPS-END
678
679
@@ -650,6 +682,7 @@ Node-kind: file
682 Node-action: change
683 Text-content-length: 2713
684 Text-content-md5: 0afbe34f244cd662b1f97d708c687f90
685 +Text-content-sha1: 46d9377d783e67a9b581da110352e799517c8a14
686 Content-length: 2713
687
688 # -DCOLLISION_CHECK if you believe that SHA1's
@@ -734,3 +767,244 @@ backup: clean
767 cd .. ; tar czvf dircache.tar.gz dir-cache
768
769
770 +Revision-number: 10
771 +Prop-content-length: 116
772 +Content-length: 116
773 +
774 +K 7
775 +svn:log
776 +V 13
777 +left update 4
778 +K 10
779 +svn:author
780 +V 8
781 +tallsopp
782 +K 8
783 +svn:date
784 +V 27
785 +2009-11-12T20:29:52.081644Z
786 +PROPS-END
787 +
788 +Node-path: branches/left/Makefile
789 +Node-kind: file
790 +Node-action: change
791 +Text-content-length: 2529
792 +Text-content-md5: f6b197cc3f2e89a83e545d4bb003de73
793 +Text-content-sha1: 2f656677cfec0bceec85e53036ffb63e25126f8e
794 +Content-length: 2529
795 +
796 +# -DCOLLISION_CHECK if you believe that SHA1's
797 +# 1461501637330902918203684832716283019655932542976 hashes do not give you
798 +# enough guarantees about no collisions between objects ever hapenning.
799 +#
800 +# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
801 +# Note that you need some new glibc (at least >2.2.4) for this, and it will
802 +# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
803 +# break unless your underlying filesystem supports those sub-second times
804 +# (my ext3 doesn't).
805 +CFLAGS=-g -O3 -Wall
806 +
807 +CC=gcc
808 +
809 +
810 +PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
811 + cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
812 + check-files ls-tree merge-base
813 +
814 +all: $(PROG)
815 +
816 +install: $(PROG)
817 + install $(PROG) $(HOME)/bin/
818 +
819 +LIBS= -lssl -lz
820 +
821 +init-db: init-db.o
822 +
823 +update-cache: update-cache.o read-cache.o
824 + $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
825 +
826 +show-diff: show-diff.o read-cache.o
827 + $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
828 +
829 +write-tree: write-tree.o read-cache.o
830 + $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
831 +
832 +read-tree: read-tree.o read-cache.o
833 + $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
834 +
835 +commit-tree: commit-tree.o read-cache.o
836 + $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
837 +
838 +cat-file: cat-file.o read-cache.o
839 + $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
840 +
841 +fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
842 + $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
843 +
844 +checkout-cache: checkout-cache.o read-cache.o
845 + $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
846 +
847 +diff-tree: diff-tree.o read-cache.o
848 + $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
849 +
850 +rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
851 + $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
852 +
853 +show-files: show-files.o read-cache.o
854 + $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
855 +
856 +check-files: check-files.o read-cache.o
857 + $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
858 +
859 +ls-tree: ls-tree.o read-cache.o
860 + $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
861 +
862 +merge-base: merge-base.o read-cache.o
863 + $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
864 +
865 +read-cache.o: cache.h
866 +show-diff.o: cache.h
867 +
868 +clean:
869 + rm -f *.o $(PROG)
870 +
871 +backup: clean
872 + cd .. ; tar czvf dircache.tar.gz dir-cache
873 +
874 +
875 +Revision-number: 11
876 +Prop-content-length: 117
877 +Content-length: 117
878 +
879 +K 7
880 +svn:log
881 +V 14
882 +right update 1
883 +K 10
884 +svn:author
885 +V 8
886 +tallsopp
887 +K 8
888 +svn:date
889 +V 27
890 +2009-11-12T20:29:53.059636Z
891 +PROPS-END
892 +
893 +Node-path: branches/right/Makefile
894 +Node-kind: file
895 +Node-action: change
896 +Text-content-length: 2593
897 +Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba
898 +Text-content-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10
899 +Content-length: 2593
900 +
901 +# -DCOLLISION_CHECK if you believe that SHA1's
902 +# 1461501637330902918203684832716283019655932542976 hashes do not give you
903 +# enough guarantees about no collisions between objects ever hapenning.
904 +#
905 +# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
906 +# Note that you need some new glibc (at least >2.2.4) for this, and it will
907 +# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
908 +# break unless your underlying filesystem supports those sub-second times
909 +# (my ext3 doesn't).
910 +CFLAGS=-g -O3 -Wall
911 +
912 +CC=gcc
913 +
914 +
915 +PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
916 + cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
917 + check-files ls-tree merge-base
918 +
919 +all: $(PROG)
920 +
921 +install: $(PROG)
922 + install $(PROG) $(HOME)/bin/
923 +
924 +LIBS= -lssl -lz
925 +
926 +init-db: init-db.o
927 +
928 +update-cache: update-cache.o read-cache.o
929 + $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
930 +
931 +show-diff: show-diff.o read-cache.o
932 + $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
933 +
934 +write-tree: write-tree.o read-cache.o
935 + $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
936 +
937 +read-tree: read-tree.o read-cache.o
938 + $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
939 +
940 +commit-tree: commit-tree.o read-cache.o
941 + $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
942 +
943 +cat-file: cat-file.o read-cache.o
944 + $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
945 +
946 +fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
947 + $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
948 +
949 +checkout-cache: checkout-cache.o read-cache.o
950 + $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
951 +
952 +diff-tree: diff-tree.o read-cache.o
953 + $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
954 +
955 +rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
956 + $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
957 +
958 +show-files: show-files.o read-cache.o
959 + $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
960 +
961 +check-files: check-files.o read-cache.o
962 + $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
963 +
964 +ls-tree: ls-tree.o read-cache.o
965 + $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
966 +
967 +merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
968 + $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
969 +
970 +read-cache.o: cache.h
971 +show-diff.o: cache.h
972 +
973 +clean:
974 + rm -f *.o $(PROG)
975 +
976 +backup: clean
977 + cd .. ; tar czvf dircache.tar.gz dir-cache
978 +
979 +
980 +Revision-number: 12
981 +Prop-content-length: 116
982 +Content-length: 116
983 +
984 +K 7
985 +svn:log
986 +V 13
987 +Merge trunk 2
988 +K 10
989 +svn:author
990 +V 8
991 +tallsopp
992 +K 8
993 +svn:date
994 +V 27
995 +2009-11-12T20:29:56.083003Z
996 +PROPS-END
997 +
998 +Node-path: trunk
999 +Node-kind: dir
1000 +Node-action: change
1001 +Prop-content-length: 54
1002 +Content-length: 54
1003 +
1004 +K 13
1005 +svn:mergeinfo
1006 +V 19
1007 +/branches/left:2-11
1008 +PROPS-END
1009 +
1010 +