commit fb8851205d3a6b7f0c457b2091c3b335d0f7e4e3 from: Mark Jamsek via: Thomas Adam date: Wed Jul 19 20:02:02 2023 UTC expand support for commit keywords to more got commands Add the ability to use keywords in the backout, branch, checkout, cherrypick, and patch commands. Includes some basic regress tests for the new commands, and also some more contrived test cases for 'got log -c[:]keyword[:(+|-)[N]]'. ok stsp commit - 481d9ea65dc2884473253a84cee23e8a562ac3b9 commit + fb8851205d3a6b7f0c457b2091c3b335d0f7e4e3 blob - 88a4286fff9c196d6fcc50a06ce49f886eb81d91 blob + 6850047d13f8afebd1c2166d9b5f9d3e689eab3b --- got/got.1 +++ got/got.1 @@ -570,6 +570,43 @@ The expected argument is a commit ID SHA1 hash or an e or tag name which will be resolved to a commit ID. An abbreviated hash argument will be expanded to a full SHA1 hash automatically, provided the abbreviation is unique. +.Pp +The special +.Ar commit +keywords +.Qq :base +and +.Qq :head +can also be used, with both resolving to the +repository's HEAD reference, or, if the +.Fl b +option is used, the head of the checked-out +.Ar branch . +Keywords and reference names may be appended with +.Qq :+ +or +.Qq :- +modifiers and an optional integer N to denote the +Nth descendant or antecedent by first parent traversal, respectively; +for example, +.Sy :head:-2 +denotes the work tree branch head's 2nd generation ancestor, and +.Sy foo:-3 +will denote the 3rd generation ancestor of the commit resolved by the +.Qq foo +reference. +If an integer does not follow the +.Qq :+ +or +.Qq :- +modifier, a +.Qq 1 +is implicitly appended +.Po e.g., +.Sy :head:- +is equivalent to +.Sy :head:-1 +.Pc . If this option is not specified, the most recent commit on the selected branch will be used. .Pp @@ -1364,6 +1401,46 @@ The expected .Ar commit argument is a commit ID SHA1 hash or an existing reference or tag name which will be resolved to a commit ID. +.Pp +The special +.Ar commit +keywords +.Qq :base +and +.Qq :head +can also be used to represent the work tree's base commit +and branch head, respectively. +The former is only valid if invoked in a work tree, while the latter will +resolve to the tip of the work tree's current branch if invoked in a +work tree, otherwise it will resolve to the repository's HEAD reference. +Keywords and references may be appended with +.Qq :+ +or +.Qq :- +modifiers and an optional integer N to denote the +Nth descendant or antecedent by first parent traversal, respectively; +for example, +.Sy :head:-2 +denotes the work tree branch head's 2nd generation ancestor, and +.Sy :base:+4 +denotes the 4th generation descendant of the work tree's base commit. +Similarly, +.Sy foobar:+3 +will denote the 3rd generation descendant of the commit resolved by the +.Qq foobar +reference. +A +.Qq :+ +or +.Qq :- +modifier without a trailing integer has an implicit +.Qq 1 +appended +.Po e.g., +.Sy :base:+ +is equivalent to +.Sy :base:+1 +.Pc . .It Fl d Ar name Delete the branch with the specified .Ar name @@ -1687,6 +1764,49 @@ are as follows: Attempt to locate files within the specified .Ar commit for use as a merge-base for 3-way merges. +The expected +.Ar commit +argument is a commit ID SHA1 hash or an existing reference +or tag name which will be resolved to a commit ID. +An abbreviated hash argument will be expanded to a full SHA1 hash +automatically, provided the abbreviation is unique. +.Pp +The special +.Ar commit +keywords +.Qq :base +and +.Qq :head +can also be used to represent the work tree's base commit +and branch head, respectively. +Keywords and references may be appended with +.Qq :+ +or +.Qq :- +modifiers and an optional integer N to denote the +Nth descendant or antecedent by first parent traversal, respectively; +for example, +.Sy :head:-2 +denotes the work tree branch head's 2nd generation ancestor, and +.Sy :base:+4 +denotes the 4th generation descendant of the work tree's base commit. +Similarly, +.Sy flan:+3 +will denote the 3rd generation descendant of the commit resolved by the +.Qq flan +reference. +A +.Qq :+ +or +.Qq :- +modifier without a trailing integer has an implicit +.Qq 1 +appended +.Po e.g., +.Sy :base:+ +is equivalent to +.Sy :base:+1 +.Pc . Ideally, the specified .Ar commit should contain versions of files which the changes contained in the @@ -2165,6 +2285,43 @@ should be on a different branch than the work tree's b The expected argument is a reference or a commit ID SHA1 hash. An abbreviated hash argument will be expanded to a full SHA1 hash automatically, provided the abbreviation is unique. +.Pp +The special +.Ar commit +keywords +.Qq :base +and +.Qq :head +can also be used to represent the work tree's base commit +and branch head, respectively. +Keywords and references may be appended with +.Qq :+ +or +.Qq :- +modifiers and an optional integer N to denote the +Nth descendant or antecedent by first parent traversal, respectively; +for example, +.Sy :head:-2 +denotes the work tree branch head's 2nd generation ancestor, and +.Sy :base:+4 +denotes the 4th generation descendant of the work tree's base commit. +Similarly, +.Sy barbaz:+3 +will denote the 3rd generation descendant of the commit resolved by the +.Qq barbaz +reference. +A +.Qq :+ +or +.Qq :- +modifier without a trailing integer has an implicit +.Qq 1 +appended +.Po e.g., +.Sy :base:+ +is equivalent to +.Sy :base:+1 +.Pc . .Pp Show the status of each affected file, using the following status codes: .Bl -column YXZ description @@ -2274,6 +2431,43 @@ The expected argument is a reference or a commit ID SH An abbreviated hash argument will be expanded to a full SHA1 hash automatically, provided the abbreviation is unique. .Pp +The special +.Ar commit +keywords +.Qq :base +and +.Qq :head +can also be used to represent the work tree's base commit +and branch head, respectively. +Keywords and references may be appended with +.Qq :+ +or +.Qq :- +modifiers and an optional integer N to denote the +Nth descendant or antecedent by first parent traversal, respectively; +for example, +.Sy :head:-2 +denotes the work tree branch head's 2nd generation ancestor, and +.Sy :base:+4 +denotes the 4th generation descendant of the work tree's base commit. +Similarly, +.Sy wip:+5 +will denote the 5th generation descendant of the commit resolved by the +.Qq wip +reference. +A +.Qq :+ +or +.Qq :- +modifier without a trailing integer has an implicit +.Qq 1 +appended +.Po e.g., +.Sy :base:+ +is equivalent to +.Sy :base:+1 +.Pc . +.Pp Show the status of each affected file, using the following status codes: .Bl -column YXZ description .It G Ta file was merged blob - c10750066ae9c0758aa2f1f088ec8fc28322b045 blob + a6d84137e09637ed152c2663015d87771e4be8d3 --- got/got.c +++ got/got.c @@ -2980,7 +2980,7 @@ cmd_checkout(int argc, char *argv[]) char *worktree_path = NULL; const char *path_prefix = ""; const char *branch_name = GOT_REF_HEAD, *refname = NULL; - char *commit_id_str = NULL; + char *commit_id_str = NULL, *keyword_idstr = NULL; struct got_object_id *commit_id = NULL; char *cwd = NULL; int ch, same_path_prefix, allow_nonempty = 0, verbosity = 0; @@ -3129,7 +3129,17 @@ cmd_checkout(int argc, char *argv[]) error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); if (error) + goto done; + + error = got_keyword_to_idstr(&keyword_idstr, commit_id_str, + repo, worktree); + if (error != NULL) goto done; + if (keyword_idstr != NULL) { + free(commit_id_str); + commit_id_str = keyword_idstr; + } + error = got_repo_match_object_id(&commit_id, NULL, commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); got_ref_list_free(&refs); @@ -6973,7 +6983,7 @@ cmd_branch(int argc, char *argv[]) struct got_reference *ref = NULL; struct got_pathlist_head paths; struct got_object_id *commit_id = NULL; - char *commit_id_str = NULL; + char *commit_id_str = NULL, *keyword_idstr = NULL;; int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -7101,6 +7111,14 @@ cmd_branch(int argc, char *argv[]) commit_id_arg = worktree ? got_worktree_get_head_ref_name(worktree) : GOT_REF_HEAD; + else { + error = got_keyword_to_idstr(&keyword_idstr, + commit_id_arg, repo, worktree); + if (error != NULL) + goto done; + if (keyword_idstr != NULL) + commit_id_arg = keyword_idstr; + } error = got_repo_match_object_id(&commit_id, NULL, commit_id_arg, GOT_OBJ_TYPE_COMMIT, &refs, repo); got_ref_list_free(&refs); @@ -7152,6 +7170,7 @@ cmd_branch(int argc, char *argv[]) } } done: + free(keyword_idstr); if (ref) got_ref_close(ref); if (repo) { @@ -8261,7 +8280,7 @@ cmd_patch(int argc, char *argv[]) const char *commit_id_str = NULL; struct stat sb; const char *errstr; - char *cwd = NULL; + char *cwd = NULL, *keyword_idstr = NULL; int ch, nop = 0, strip = -1, reverse = 0; int patchfd; int *pack_fds = NULL; @@ -8350,8 +8369,14 @@ cmd_patch(int argc, char *argv[]) goto done; if (commit_id_str != NULL) { + error = got_keyword_to_idstr(&keyword_idstr, commit_id_str, + repo, worktree); + if (error != NULL) + goto done; + error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); + keyword_idstr != NULL ? keyword_idstr : commit_id_str, + GOT_OBJ_TYPE_COMMIT, &refs, repo); if (error) goto done; } @@ -8362,6 +8387,7 @@ cmd_patch(int argc, char *argv[]) print_patch_progress_stats(&ppa); done: got_ref_list_free(&refs); + free(keyword_idstr); free(commit_id); if (repo) { close_error = got_repo_close(repo); @@ -10193,7 +10219,7 @@ cmd_cherrypick(int argc, char *argv[]) const struct got_error *error = NULL; struct got_worktree *worktree = NULL; struct got_repository *repo = NULL; - char *cwd = NULL, *commit_id_str = NULL; + char *cwd = NULL, *commit_id_str = NULL, *keyword_idstr = NULL; struct got_object_id *commit_id = NULL; struct got_commit_object *commit = NULL; struct got_object_qid *pid; @@ -10273,7 +10299,12 @@ cmd_cherrypick(int argc, char *argv[]) goto done; } - error = got_repo_match_object_id(&commit_id, NULL, argv[0], + error = got_keyword_to_idstr(&keyword_idstr, argv[0], repo, worktree); + if (error != NULL) + goto done; + + error = got_repo_match_object_id(&commit_id, NULL, + keyword_idstr != NULL ? keyword_idstr : argv[0], GOT_OBJ_TYPE_COMMIT, NULL, repo); if (error) goto done; @@ -10302,6 +10333,7 @@ cmd_cherrypick(int argc, char *argv[]) print_merge_progress_stats(&upa); done: free(cwd); + free(keyword_idstr); if (commit) got_object_commit_close(commit); free(commit_id_str); @@ -10335,7 +10367,7 @@ cmd_backout(int argc, char *argv[]) const struct got_error *error = NULL; struct got_worktree *worktree = NULL; struct got_repository *repo = NULL; - char *cwd = NULL, *commit_id_str = NULL; + char *cwd = NULL, *commit_id_str = NULL, *keyword_idstr = NULL; struct got_object_id *commit_id = NULL; struct got_commit_object *commit = NULL; struct got_object_qid *pid; @@ -10415,7 +10447,12 @@ cmd_backout(int argc, char *argv[]) goto done; } - error = got_repo_match_object_id(&commit_id, NULL, argv[0], + error = got_keyword_to_idstr(&keyword_idstr, argv[0], repo, worktree); + if (error != NULL) + goto done; + + error = got_repo_match_object_id(&commit_id, NULL, + keyword_idstr != NULL ? keyword_idstr : argv[0], GOT_OBJ_TYPE_COMMIT, NULL, repo); if (error) goto done; @@ -10448,6 +10485,7 @@ cmd_backout(int argc, char *argv[]) print_merge_progress_stats(&upa); done: free(cwd); + free(keyword_idstr); if (commit) got_object_commit_close(commit); free(commit_id_str); blob - 86b8cddd9616882e06b859c2bd3e8de87a317150 blob + 76bc77fd0afea94f3494da3f05e3f617d0019853 --- regress/cmdline/backout.sh +++ regress/cmdline/backout.sh @@ -533,13 +533,108 @@ test_backout_logmsg_ref() { ymd=`date -u -r $b2_commit_time2 +"%F"` echo "Deleted: $ymd newbranch2 $b2_logmsg2" > $testroot/stdout.expected (cd $testroot/repo && got backout -X > $testroot/stdout) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + + test_done "$testroot" "$ret" +} + +test_backout_commit_keywords() { + local testroot=$(test_init backout_commit_keywords) + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "new" > $testroot/wt/new + (cd $testroot/wt && got add new > /dev/null) + echo "modified alpha" > $testroot/wt/alpha + (cd $testroot/wt && got rm epsilon/zeta > /dev/null) + (cd $testroot/wt && got commit -m "bad changes" > /dev/null) + + local bad_commit=`git_show_head $testroot/repo` + + (cd $testroot/wt && got update > /dev/null) + + echo "modified beta" > $testroot/wt/beta + (cd $testroot/wt && got commit -m "changing beta" > /dev/null) + echo "modified beta again" > $testroot/wt/beta + (cd $testroot/wt && got commit -m "changing beta again" > /dev/null) + + (cd $testroot/wt && got update > /dev/null) + + (cd $testroot/wt && got bo :head:-2 > $testroot/stdout) + + echo "G alpha" > $testroot/stdout.expected + echo "A epsilon/zeta" >> $testroot/stdout.expected + echo "D new" >> $testroot/stdout.expected + echo "Backed out commit $bad_commit" >> $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + echo "alpha" > $testroot/content.expected + cat $testroot/wt/alpha > $testroot/content + cmp -s $testroot/content.expected $testroot/content + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/content.expected $testroot/content + test_done "$testroot" "$ret" + return 1 + fi + + if [ -e "$testroot/wt/new" ]; then + echo "file '$testroot/wt/new' still exists on disk" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + if [ ! -e "$testroot/wt/epsilon/zeta" ]; then + echo "file '$testroot/wt/epsilon/zeta' is missing on disk" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + echo 'M alpha' > $testroot/stdout.expected + echo 'A epsilon/zeta' >> $testroot/stdout.expected + echo 'D new' >> $testroot/stdout.expected + (cd $testroot/wt && got status > $testroot/stdout) + cmp -s $testroot/stdout.expected $testroot/stdout ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 fi + local next_backout=`git_show_head $testroot/repo` + + (cd "$testroot/wt" && got ci -m "backed-out bad commit" > /dev/null) + (cd "$testroot/wt" && got up > /dev/null) + + echo "G beta" > $testroot/stdout.expected + echo "Backed out commit $next_backout" >> $testroot/stdout.expected + (cd "$testroot/wt" && got bo :base:- > $testroot/stdout) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" } @@ -549,3 +644,4 @@ run_test test_backout_edits_for_file_since_deleted run_test test_backout_next_commit run_test test_backout_umask run_test test_backout_logmsg_ref +run_test test_backout_commit_keywords blob - cab7171d5632c0bdf72e14e1d6dda98d3a4ce810 blob + 71213582275291870b3a3f5941f02a76914cc1c1 --- regress/cmdline/branch.sh +++ regress/cmdline/branch.sh @@ -527,6 +527,52 @@ test_branch_packed_ref_collision() { echo "* zoo: $commit_id2" > $testroot/stdout.expected echo " master: $commit_id" >> $testroot/stdout.expected cmp -s $testroot/stdout $testroot/stdout.expected + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + test_done "$testroot" "$ret" +} + +test_branch_commit_keywords() { + local testroot=$(test_init branch_commit_keywords) + + set -A ids "$(git_show_head $testroot/repo)" + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + echo "checkout failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + for i in $(seq 4); do + echo "beta change $i" > "$testroot/wt/beta" + + (cd "$testroot/wt" && got ci -m "commit number $i" > /dev/null) + ret=$? + if [ $ret -ne 0 ]; then + echo "commit failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + set -- "$ids" "$(git_show_head $testroot/repo)" + ids=$* + done + + (cd "$testroot/wt" && got up > /dev/null) + + echo " kwbranch: $(pop_id 3 $ids)" > $testroot/stdout.expected + echo " master: $(pop_id 5 $ids)" >> $testroot/stdout.expected + + (cd "$testroot/wt" && got br -nc :head:-2 kwbranch > /dev/null) + got br -r "$testroot/repo" -l > "$testroot/stdout" + + cmp -s $testroot/stdout.expected $testroot/stdout ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/stdout.expected $testroot/stdout @@ -534,6 +580,17 @@ test_branch_packed_ref_collision() { return 1 fi + echo " kwbranch2: $(pop_id 4 $ids)" > $testroot/stdout.expected + + got br -r "$testroot/repo" -c master:- kwbranch2 > /dev/null + got br -r "$testroot/repo" -l | grep kwbranch2 > "$testroot/stdout" + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" } @@ -545,3 +602,4 @@ run_test test_branch_delete_current_branch run_test test_branch_delete_packed run_test test_branch_show run_test test_branch_packed_ref_collision +run_test test_branch_commit_keywords blob - 9403e4715c6ed077315fb8b1bcb68bccd4247176 blob + 9bdce2b8a07cd2893ca474983afc996ca236d190 --- regress/cmdline/checkout.sh +++ regress/cmdline/checkout.sh @@ -928,7 +928,82 @@ test_checkout_ulimit_n() { ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/content.expected $testroot/content + fi + test_done "$testroot" "$ret" +} + +test_checkout_commit_keywords() { + local testroot=$(test_init checkout_commit_keywords) + + set -A ids "$(git_show_head $testroot/repo)" + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + echo "checkout failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + for i in $(seq 4); do + echo "zeta change $i" > "$testroot/wt/epsilon/zeta" + + (cd "$testroot/wt" && got ci -m "commit number $i" > /dev/null) + ret=$? + if [ $ret -ne 0 ]; then + echo "commit failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + set -- "$ids" "$(git_show_head $testroot/repo)" + ids=$* + done + + echo "A $testroot/wt2/alpha" > $testroot/stdout.expected + echo "A $testroot/wt2/beta" >> $testroot/stdout.expected + echo "A $testroot/wt2/epsilon/zeta" >> $testroot/stdout.expected + echo "A $testroot/wt2/gamma/delta" >> $testroot/stdout.expected + echo "Checked out refs/heads/master: $(pop_id 4 $ids)" \ + >> $testroot/stdout.expected + echo "Now shut up and hack" >> $testroot/stdout.expected + + got co -c :head:- $testroot/repo $testroot/wt2 > $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 fi + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "A $testroot/wt3/alpha" > $testroot/stdout.expected + echo "A $testroot/wt3/beta" >> $testroot/stdout.expected + echo "A $testroot/wt3/epsilon/zeta" >> $testroot/stdout.expected + echo "A $testroot/wt3/gamma/delta" >> $testroot/stdout.expected + echo "Checked out refs/heads/master: $(pop_id 4 $ids)" \ + >> $testroot/stdout.expected + echo "Now shut up and hack" >> $testroot/stdout.expected + + got co -bmaster -c:base:- $testroot/repo $testroot/wt3 > \ + $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" } @@ -948,3 +1023,4 @@ run_test test_checkout_repo_with_unknown_extension run_test test_checkout_quiet run_test test_checkout_umask run_test test_checkout_ulimit_n +run_test test_checkout_commit_keywords blob - 364fe8dd78d0449f3b9718c310a7ead6bddbe3a6 blob + 8de61842e9e87808d61b276b6d639e2f1b7d5e09 --- regress/cmdline/cherrypick.sh +++ regress/cmdline/cherrypick.sh @@ -2028,6 +2028,68 @@ test_cherrypick_logmsg_ref() { test_done "$testroot" "$ret" } +test_cherrypick_commit_keywords() { + local testroot=`test_init cherrypick_commit_keywords` + + set -A ids "$(git_show_head $testroot/repo)" + + (cd $testroot/repo && git checkout -q -b branch-1) + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + echo "checkout failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + echo "changed on branch-1" >> "$testroot/repo/alpha" + git_commit $testroot/repo -m "alpha changed on branch-1" + set -- "$ids" "$(git_show_head $testroot/repo)" + ids=$* + + for i in $(seq 4); do + echo "branch-1 change $i" >> "$testroot/repo/gamma/delta" + + git_commit $testroot/repo -m "commit number $i" + set -- "$ids" "$(git_show_head $testroot/repo)" + ids=$* + done + + echo "G alpha" > $testroot/stdout.expected + echo "Merged commit $(pop_id 2 $ids)" >> $testroot/stdout.expected + + (cd "$testroot/wt" && got cy master:+ > $testroot/stdout) + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + (cd "$testroot/wt" && got rv alpha > /dev/null) + + echo "C gamma/delta" > $testroot/stdout.expected + echo "Merged commit $(pop_id 5 $ids)" >> $testroot/stdout.expected + echo "Files with new merge conflicts: 1" >> $testroot/stdout.expected + (cd "$testroot/wt" && got cy branch-1:- > $testroot/stdout) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + + test_done "$testroot" "$ret" +} + test_parseargs "$@" run_test test_cherrypick_basic run_test test_cherrypick_root_commit @@ -2047,3 +2109,4 @@ run_test test_cherrypick_dot_on_a_line_by_itself run_test test_cherrypick_binary_file run_test test_cherrypick_umask run_test test_cherrypick_logmsg_ref +run_test test_cherrypick_commit_keywords blob - 96004ce8b8a631507d11bbb3ba545448a1a16429 blob + 58e79bdb23ae3a08aa668ad20b439963c6eda8d1 --- regress/cmdline/log.sh +++ regress/cmdline/log.sh @@ -1043,8 +1043,111 @@ test_log_commit_keywords() { ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 fi + + echo "got: '::base:+': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -c::base:+ 2> $testroot/stderr) + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: ':head:-:': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -c:head:-: 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: 'master::+': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -cmaster::+ 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: 'master:1+': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -cmaster:1+ 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: ':base:-1:base:-1': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -c:base:-1:base:-1 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: 'main:-main:-': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -cmain:-main:- 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: ':base:*1': invalid commit keyword" > \ + $testroot/stderr.expected + + (cd $testroot/wt && got log -c:base:*1 2> $testroot/stderr) + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: reference null not found" > $testroot/stderr.expected + + (cd $testroot/wt && got log -cnull:+ 2> $testroot/stderr) + + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr + fi + test_done "$testroot" "$ret" } blob - 17db471e5c3aa81e0eb9233b406861cdccd08fcd blob + f95aac7980de13e20863266dcd1ae971cb702364 --- regress/cmdline/patch.sh +++ regress/cmdline/patch.sh @@ -1955,7 +1955,91 @@ test_patch_remove_binary_file() { test_done $testroot 0 } + +test_patch_commit_keywords() { + local testroot=`test_init patch_commit_keywords` + + got checkout $testroot/repo $testroot/wt >/dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + jot 10 > $testroot/wt/numbers + (cd $testroot/wt && got add numbers && got commit -m +numbers) \ + >/dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + jot 10 | sed s/4/four/ > $testroot/wt/numbers + + # get rid of the metadata + (cd $testroot/wt && got diff | sed -n '/^---/,$p' > patch) \ + >/dev/null + jot 10 | sed s/6/six/ > $testroot/wt/numbers + (cd $testroot/wt && got commit -m 'edit numbers') >/dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + (cd $testroot/wt && got patch -c :head:- patch) >$testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + echo 'G numbers' > $testroot/stdout.expected + cmp -s $testroot/stdout $testroot/stdout.expected + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout $testroot/stdout.expected + test_done $testroot $ret + return 1 + fi + + jot 10 | sed -e s/4/four/ -e s/6/six/ > $testroot/wt/numbers.expected + cmp -s $testroot/wt/numbers $testroot/wt/numbers.expected + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/wt/numbers $testroot/wt/numbers.expected + fi + + (cd "$testroot/wt" && got rv numbers > /dev/null) + + (cd $testroot/wt && got patch -c :base:- patch) >$testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + echo 'G numbers' > $testroot/stdout.expected + cmp -s $testroot/stdout $testroot/stdout.expected + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout $testroot/stdout.expected + test_done $testroot $ret + return 1 + fi + + jot 10 | sed -e s/4/four/ -e s/6/six/ > $testroot/wt/numbers.expected + cmp -s $testroot/wt/numbers $testroot/wt/numbers.expected + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/wt/numbers $testroot/wt/numbers.expected + fi + + test_done $testroot $ret +} + test_parseargs "$@" run_test test_patch_basic run_test test_patch_dont_apply @@ -1986,3 +2070,4 @@ run_test test_patch_newfile_xbit_got_diff run_test test_patch_newfile_xbit_git_diff run_test test_patch_umask run_test test_patch_remove_binary_file +run_test test_patch_commit_keywords