diff options
-rw-r--r-- | Documentation/RelNotes/1.7.10.txt | 9 | ||||
-rw-r--r-- | Documentation/RelNotes/1.7.8.5.txt | 19 | ||||
-rw-r--r-- | Documentation/RelNotes/1.7.9.3.txt | 17 | ||||
-rw-r--r-- | Documentation/git-p4.txt | 10 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rwxr-xr-x | contrib/fast-import/git-p4 | 97 | ||||
-rwxr-xr-x | git-am.sh | 2 | ||||
-rw-r--r-- | git-rebase--merge.sh | 11 | ||||
-rw-r--r-- | grep.c | 2 | ||||
-rwxr-xr-x | t/t4150-am.sh | 10 | ||||
-rwxr-xr-x | t/t9800-git-p4-basic.sh | 24 | ||||
-rwxr-xr-x | t/t9809-git-p4-client-view.sh | 161 |
12 files changed, 291 insertions, 72 deletions
diff --git a/Documentation/RelNotes/1.7.10.txt b/Documentation/RelNotes/1.7.10.txt index 0add762b0a..364e16d0d5 100644 --- a/Documentation/RelNotes/1.7.10.txt +++ b/Documentation/RelNotes/1.7.10.txt @@ -87,15 +87,6 @@ Unless otherwise noted, all the fixes since v1.7.9 in the maintenance releases are contained in this release (see release notes to them for details). - * The config.mak.autogen generated by optional autoconf support tried - to link the binary with -lintl even when libintl.h is missing from - the system. - (merge a8356d4 js/configure-libintl later to maint). - - * "git add --refresh <pathspec>" used to warn about unmerged paths - outside the given pathspec. - (merge 3d1f148 jc/add-refresh-unmerged later to maint). - * "gitweb" used to drop warnings in the log file when "heads" view is accessed in a repository whose HEAD does not point at a valid branch. diff --git a/Documentation/RelNotes/1.7.8.5.txt b/Documentation/RelNotes/1.7.8.5.txt new file mode 100644 index 0000000000..011fd2a428 --- /dev/null +++ b/Documentation/RelNotes/1.7.8.5.txt @@ -0,0 +1,19 @@ +Git v1.7.8.5 Release Notes +========================== + +Fixes since v1.7.8.4 +-------------------- + + * Dependency on our thread-utils.h header file was missing for + objects that depend on it in the Makefile. + + * "git am" when fed an empty file did not correctly finish reading it + when it attempts to guess the input format. + + * "git grep -P" (when PCRE is enabled in the build) did not match the + beginning and the end of the line correctly with ^ and $. + + * "git rebase -m" tried to run "git notes copy" needlessly when + nothing was rewritten. + +Also contains minor fixes and documentation updates. diff --git a/Documentation/RelNotes/1.7.9.3.txt b/Documentation/RelNotes/1.7.9.3.txt new file mode 100644 index 0000000000..1d03fd10c0 --- /dev/null +++ b/Documentation/RelNotes/1.7.9.3.txt @@ -0,0 +1,17 @@ +Git v1.7.9.3 Release Notes +========================== + +Fixes since v1.7.9.2 +-------------------- + + * "git p4" (in contrib/) submit the changes to a wrong place when the + "--use-client-spec" option is set. + + * The config.mak.autogen generated by optional autoconf support tried + to link the binary with -lintl even when libintl.h is missing from + the system. + + * "git add --refresh <pathspec>" used to warn about unmerged paths + outside the given pathspec. + +Also contains minor fixes and documentation updates. diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 3fecefaea2..b7c7929716 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -303,9 +303,13 @@ CLIENT SPEC ----------- The p4 client specification is maintained with the 'p4 client' command and contains among other fields, a View that specifies how the depot -is mapped into the client repository. Git-p4 can consult the client -spec when given the '--use-client-spec' option or useClientSpec -variable. +is mapped into the client repository. The 'clone' and 'sync' commands +can consult the client spec when given the '--use-client-spec' option or +when the useClientSpec variable is true. After 'git p4 clone', the +useClientSpec variable is automatically set in the repository +configuration file. This allows future 'git p4 submit' commands to +work properly; the submit command looks only at the variable and does +not have a command-line option. The full syntax for a p4 view is documented in 'p4 help views'. Git-p4 knows only a subset of the view syntax. It understands multi-line @@ -620,6 +620,7 @@ LIB_H += streaming.h LIB_H += string-list.h LIB_H += submodule.h LIB_H += tag.h +LIB_H += thread-utils.h LIB_H += transport.h LIB_H += tree.h LIB_H += tree-walk.h diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 053955349a..c5362c4c11 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -596,6 +596,46 @@ def p4PathStartsWith(path, prefix): return path.lower().startswith(prefix.lower()) return path.startswith(prefix) +def getClientSpec(): + """Look at the p4 client spec, create a View() object that contains + all the mappings, and return it.""" + + specList = p4CmdList("client -o") + if len(specList) != 1: + die('Output from "client -o" is %d lines, expecting 1' % + len(specList)) + + # dictionary of all client parameters + entry = specList[0] + + # just the keys that start with "View" + view_keys = [ k for k in entry.keys() if k.startswith("View") ] + + # hold this new View + view = View() + + # append the lines, in order, to the view + for view_num in range(len(view_keys)): + k = "View%d" % view_num + if k not in view_keys: + die("Expected view key %s missing" % k) + view.append(entry[k]) + + return view + +def getClientRoot(): + """Grab the client directory.""" + + output = p4CmdList("client -o") + if len(output) != 1: + die('Output from "client -o" is %d lines, expecting 1' % len(output)) + + entry = output[0] + if "Root" not in entry: + die('Client has no "Root"') + + return entry["Root"] + class Command: def __init__(self): self.usage = "usage: %prog [options]" @@ -1220,11 +1260,20 @@ class P4Submit(Command, P4UserMap): print "Internal error: cannot locate perforce depot path from existing branches" sys.exit(128) - self.clientPath = p4Where(self.depotPath) + self.useClientSpec = False + if gitConfig("git-p4.useclientspec", "--bool") == "true": + self.useClientSpec = True + if self.useClientSpec: + self.clientSpecDirs = getClientSpec() - if len(self.clientPath) == 0: - print "Error: Cannot locate perforce checkout of %s in client view" % self.depotPath - sys.exit(128) + if self.useClientSpec: + # all files are relative to the client spec + self.clientPath = getClientRoot() + else: + self.clientPath = p4Where(self.depotPath) + + if self.clientPath == "": + die("Error: Cannot locate perforce checkout of %s in client view" % self.depotPath) print "Perforce checkout for depot path %s located at %s" % (self.depotPath, self.clientPath) self.oldWorkingDirectory = os.getcwd() @@ -1530,6 +1579,7 @@ class P4Sync(Command, P4UserMap): self.p4BranchesInGit = [] self.cloneExclude = [] self.useClientSpec = False + self.useClientSpec_from_options = False self.clientSpecDirs = None self.tempBranches = [] self.tempBranchLocation = "git-p4-tmp" @@ -2223,33 +2273,6 @@ class P4Sync(Command, P4UserMap): print self.gitError.read() - def getClientSpec(self): - specList = p4CmdList("client -o") - if len(specList) != 1: - die('Output from "client -o" is %d lines, expecting 1' % - len(specList)) - - # dictionary of all client parameters - entry = specList[0] - - # just the keys that start with "View" - view_keys = [ k for k in entry.keys() if k.startswith("View") ] - - # hold this new View - view = View() - - # append the lines, in order, to the view - for view_num in range(len(view_keys)): - k = "View%d" % view_num - if k not in view_keys: - die("Expected view key %s missing" % k) - view.append(entry[k]) - - self.clientSpecDirs = view - if self.verbose: - for i, m in enumerate(self.clientSpecDirs.mappings): - print "clientSpecDirs %d: %s" % (i, str(m)) - def run(self, args): self.depotPaths = [] self.changeRange = "" @@ -2282,11 +2305,15 @@ class P4Sync(Command, P4UserMap): if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch): system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch)) - if not self.useClientSpec: + # accept either the command-line option, or the configuration variable + if self.useClientSpec: + # will use this after clone to set the variable + self.useClientSpec_from_options = True + else: if gitConfig("git-p4.useclientspec", "--bool") == "true": self.useClientSpec = True if self.useClientSpec: - self.getClientSpec() + self.clientSpecDirs = getClientSpec() # TODO: should always look at previous commits, # merge with previous imports, if possible. @@ -2607,6 +2634,10 @@ class P4Clone(P4Sync): else: print "Could not detect main branch. No checkout/master branch created." + # auto-set this variable if invoked with --use-client-spec + if self.useClientSpec_from_options: + system("git config --bool git-p4.useclientspec true") + return True class P4Branches(Command): @@ -202,7 +202,7 @@ check_patch_format () { l1= while test -z "$l1" do - read l1 + read l1 || break done read l2 read l3 diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh index 26afc75cc7..dc599077f0 100644 --- a/git-rebase--merge.sh +++ b/git-rebase--merge.sh @@ -90,10 +90,13 @@ call_merge () { finish_rb_merge () { move_to_original_branch - git notes copy --for-rewrite=rebase < "$state_dir"/rewritten - if test -x "$GIT_DIR"/hooks/post-rewrite && - test -s "$state_dir"/rewritten; then - "$GIT_DIR"/hooks/post-rewrite rebase < "$state_dir"/rewritten + if test -s "$state_dir"/rewritten + then + git notes copy --for-rewrite=rebase <"$state_dir"/rewritten + if test -x "$GIT_DIR"/hooks/post-rewrite + then + "$GIT_DIR"/hooks/post-rewrite rebase <"$state_dir"/rewritten + fi fi rm -r "$state_dir" say All done. @@ -79,7 +79,7 @@ static void compile_pcre_regexp(struct grep_pat *p, const struct grep_opt *opt) { const char *error; int erroffset; - int options = 0; + int options = PCRE_MULTILINE; if (opt->ignore_case) options |= PCRE_CASELESS; diff --git a/t/t4150-am.sh b/t/t4150-am.sh index f1b60b8560..6f77fffee6 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -505,4 +505,14 @@ test_expect_success 'am -q is quiet' ' ! test -s output.out ' +test_expect_success 'am empty-file does not infloop' ' + rm -fr .git/rebase-apply && + git reset --hard && + touch empty-file && + test_tick && + { git am empty-file > actual 2>&1 && false || :; } && + echo Patch format detection failed. >expected && + test_cmp expected actual +' + test_done diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index 04ee20e642..486c8eeb7e 100755 --- a/t/t9800-git-p4-basic.sh +++ b/t/t9800-git-p4-basic.sh @@ -234,8 +234,10 @@ test_expect_success 'refuse to preserve users without perms' ' git config git-p4.skipSubmitEditCheck true && echo "username-noperms: a change by alice" >>file1 && git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 && - P4EDITOR=touch P4USER=bob P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user && - test_must_fail git diff --exit-code HEAD..p4/master + P4EDITOR=touch P4USER=bob P4PASSWD=secret && + export P4EDITOR P4USER P4PASSWD && + test_must_fail "$GITP4" commit --preserve-user && + ! git diff --exit-code HEAD..p4/master ) ' @@ -250,13 +252,15 @@ test_expect_success 'preserve user where author is unknown to p4' ' git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 && echo "username-unknown: a change by charlie" >>file1 && git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 && - P4EDITOR=touch P4USER=alice P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user && - test_must_fail git diff --exit-code HEAD..p4/master && + P4EDITOR=touch P4USER=alice P4PASSWD=secret && + export P4EDITOR P4USER P4PASSWD && + test_must_fail "$GITP4" commit --preserve-user && + ! git diff --exit-code HEAD..p4/master && echo "$0: repeat with allowMissingP4Users enabled" && git config git-p4.allowMissingP4Users true && git config git-p4.preserveUser true && - P4EDITOR=touch P4USER=alice P4PASSWD=secret "$GITP4" commit && + "$GITP4" commit && git diff --exit-code HEAD..p4/master && p4_check_commit_author file1 alice ) @@ -275,20 +279,22 @@ test_expect_success 'not preserving user with mixed authorship' ' p4_add_user derek Derek && make_change_by_user usernamefile3 Derek derek@localhost && - P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\ + P4EDITOR=cat P4USER=alice P4PASSWD=secret && + export P4EDITOR P4USER P4PASSWD && + "$GITP4" commit |\ grep "git author derek@localhost does not match" && make_change_by_user usernamefile3 Charlie charlie@localhost && - P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\ + "$GITP4" commit |\ grep "git author charlie@localhost does not match" && make_change_by_user usernamefile3 alice alice@localhost && - P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" |\ + "$GITP4" commit |\ test_must_fail grep "git author.*does not match" && git config git-p4.skipUserNameCheck true && make_change_by_user usernamefile3 Charlie charlie@localhost && - P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\ + "$GITP4" commit |\ test_must_fail grep "git author.*does not match" && p4_check_commit_author usernamefile3 alice diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh index ae9145e307..773a516ff0 100755 --- a/t/t9809-git-p4-client-view.sh +++ b/t/t9809-git-p4-client-view.sh @@ -31,7 +31,7 @@ client_view() { # check_files_exist() { ok=0 && - num=${#@} && + num=$# && for arg ; do test_path_is_file "$arg" && ok=$(($ok + 1)) @@ -71,20 +71,24 @@ git_verify() { # - dir2 # - file21 # - file22 +init_depot() { + for d in 1 2 ; do + mkdir -p dir$d && + for f in 1 2 ; do + echo dir$d/file$d$f >dir$d/file$d$f && + p4 add dir$d/file$d$f && + p4 submit -d "dir$d/file$d$f" + done + done && + find . -type f ! -name files >files && + check_files_exist dir1/file11 dir1/file12 \ + dir2/file21 dir2/file22 +} + test_expect_success 'init depot' ' ( cd "$cli" && - for d in 1 2 ; do - mkdir -p dir$d && - for f in 1 2 ; do - echo dir$d/file$d$f >dir$d/file$d$f && - p4 add dir$d/file$d$f && - p4 submit -d "dir$d/file$d$f" - done - done && - find . -type f ! -name files >files && - check_files_exist dir1/file11 dir1/file12 \ - dir2/file21 dir2/file22 + init_depot ) ' @@ -247,6 +251,139 @@ test_expect_success 'quotes on rhs only' ' ' # +# Submit tests +# + +# clone sets variable +test_expect_success 'clone --use-client-spec sets useClientSpec' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot && + ( + cd "$git" && + git config --bool git-p4.useClientSpec >actual && + echo true >true && + test_cmp actual true + ) +' + +# clone just a subdir of the client spec +test_expect_success 'subdir clone' ' + client_view "//depot/... //client/..." && + files="dir1/file11 dir1/file12 dir2/file21 dir2/file22" && + client_verify $files && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + git_verify dir1/file11 dir1/file12 +' + +# +# submit back, see what happens: five cases +# +test_expect_success 'subdir clone, submit modify' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + echo line >>dir1/file12 && + git add dir1/file12 && + git commit -m dir1/file12 && + "$GITP4" submit + ) && + ( + cd "$cli" && + test_path_is_file dir1/file12 && + test_line_count = 2 dir1/file12 + ) +' + +test_expect_success 'subdir clone, submit add' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + echo file13 >dir1/file13 && + git add dir1/file13 && + git commit -m dir1/file13 && + "$GITP4" submit + ) && + ( + cd "$cli" && + test_path_is_file dir1/file13 + ) +' + +test_expect_success 'subdir clone, submit delete' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + git rm dir1/file12 && + git commit -m "delete dir1/file12" && + "$GITP4" submit + ) && + ( + cd "$cli" && + test_path_is_missing dir1/file12 + ) +' + +test_expect_success 'subdir clone, submit copy' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + git config git-p4.detectCopies true && + cp dir1/file11 dir1/file11a && + git add dir1/file11a && + git commit -m "copy to dir1/file11a" && + "$GITP4" submit + ) && + ( + cd "$cli" && + test_path_is_file dir1/file11a + ) +' + +test_expect_success 'subdir clone, submit rename' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + git config git-p4.detectRenames true && + git mv dir1/file13 dir1/file13a && + git commit -m "rename dir1/file13 to dir1/file13a" && + "$GITP4" submit + ) && + ( + cd "$cli" && + test_path_is_missing dir1/file13 && + test_path_is_file dir1/file13a + ) +' + +test_expect_success 'reinit depot' ' + ( + cd "$cli" && + p4 sync -f && + rm files && + p4 delete */* && + p4 submit -d "delete all files" && + init_depot + ) +' + +# # What happens when two files of the same name are overlayed together? # The last-listed file should take preference. # |