commit 1430b4e093e8dcc1a214e26991cd06d3992db829 from: Stefan Sperling date: Wed Mar 27 07:18:28 2019 UTC treat 'add vs add' on update as a text conflict for now commit - a7c182ac81f43ee290d92ff16781ea0b908c33c3 commit + 1430b4e093e8dcc1a214e26991cd06d3992db829 blob - c7e43f24fcf6a959ee0878eb5068515bd4b4ffdd blob + cd22378a777b353c7f39ca3b244c95414d187c8a --- lib/worktree.c +++ lib/worktree.c @@ -714,7 +714,6 @@ merge_blob(struct got_worktree *worktree, struct got_f FILE *f1 = NULL, *f2 = NULL; char *blob1_path = NULL, *blob2_path = NULL; char *merged_path = NULL, *base_path = NULL; - struct got_object_id id2; char *id_str = NULL; char *label1 = NULL; int overlapcnt = 0, update_timestamps = 0; @@ -753,16 +752,24 @@ merge_blob(struct got_worktree *worktree, struct got_f } err = got_opentemp_named(&blob2_path, &f2, base_path); - if (err) - goto done; - - memcpy(id2.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH); - err = got_object_open_as_blob(&blob2, repo, &id2, 8192); if (err) goto done; - err = got_object_blob_dump_to_file(NULL, NULL, f2, blob2); - if (err) - goto done; + if (got_fileindex_entry_has_blob(ie)) { + struct got_object_id id2; + memcpy(id2.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH); + err = got_object_open_as_blob(&blob2, repo, &id2, 8192); + if (err) + goto done; + err = got_object_blob_dump_to_file(NULL, NULL, f2, blob2); + if (err) + goto done; + } else { + /* + * If the file has no blob, this is an "add vs add" conflict, + * and we simply use an empty ancestor file to make both files + * appear in the merged result in their entirety. + */ + } err = got_object_id_str(&id_str, worktree->base_commit_id); if (err) @@ -1081,14 +1088,16 @@ update_blob(struct got_worktree *worktree, } if (ie && status != GOT_STATUS_MISSING) { - if (memcmp(ie->commit_sha1, worktree->base_commit_id->sha1, + if (got_fileindex_entry_has_commit(ie) && + memcmp(ie->commit_sha1, worktree->base_commit_id->sha1, SHA1_DIGEST_LENGTH) == 0) { (*progress_cb)(progress_arg, GOT_STATUS_EXISTS, path); goto done; } - if (memcmp(ie->blob_sha1, - te->id->sha1, SHA1_DIGEST_LENGTH) == 0) + if (got_fileindex_entry_has_blob(ie) && + memcmp(ie->blob_sha1, te->id->sha1, + SHA1_DIGEST_LENGTH) == 0) goto done; } @@ -1096,7 +1105,7 @@ update_blob(struct got_worktree *worktree, if (err) goto done; - if (status == GOT_STATUS_MODIFY) + if (status == GOT_STATUS_MODIFY || status == GOT_STATUS_ADD) err = merge_blob(worktree, fileindex, ie, ondisk_path, path, te->mode, sb.st_mode, blob, repo, progress_cb, progress_arg); blob - f9501623254c8d3ca0f2fc660ad0840dd9d06a5e blob + 897edc348bc687fb78ec40cb8f22235edb39e7cb --- regress/cmdline/update.sh +++ regress/cmdline/update.sh @@ -839,7 +839,56 @@ function test_update_restores_missing_file { echo "alpha" > $testroot/content.expected cat $testroot/wt/alpha > $testroot/content + + cmp $testroot/content.expected $testroot/content + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/content.expected $testroot/content + fi + test_done "$testroot" "$ret" +} + +function test_update_conflict_add_vs_add { + local testroot=`test_init update_conflict_add_vs_add` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret="$?" + if [ "$ret" != "0" ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "new" > $testroot/repo/gamma/new + (cd $testroot/repo && git add .) + git_commit $testroot/repo -m "adding a new file" + + echo "also new" > $testroot/wt/gamma/new + (cd $testroot/wt && got add gamma/new >/dev/null) + + (cd $testroot/wt && got update > $testroot/stdout) + echo "C gamma/new" > $testroot/stdout.expected + echo -n "Updated to commit " >> $testroot/stdout.expected + git_show_head $testroot/repo >> $testroot/stdout.expected + echo >> $testroot/stdout.expected + cmp $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo -n "<<<<<<< commit " > $testroot/content.expected + git_show_head $testroot/repo >> $testroot/content.expected + echo >> $testroot/content.expected + echo "new" >> $testroot/content.expected + echo "=======" >> $testroot/content.expected + echo "also new" >> $testroot/content.expected + echo '>>>>>>> gamma/new' >> $testroot/content.expected + + cat $testroot/wt/gamma/new > $testroot/content + cmp $testroot/content.expected $testroot/content ret="$?" if [ "$ret" != "0" ]; then @@ -865,3 +914,4 @@ run_test test_update_merges_file_edits run_test test_update_keeps_xbit run_test test_update_clears_xbit run_test test_update_restores_missing_file +run_test test_update_conflict_add_vs_add