git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 2/2] Let deny.currentBranch=updateInstead ignore submodules

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 2, 2014, 03:24 UTC
Message-ID
<xmqqa936ohs3.fsf@gitster.dls.corp.google.com>
In-Reply-To
<xmqq1tp643yb.fsf@gitster.dls.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
Show 22 quoted lines
>> And thinking about the names again, I have a feeling that
>> updateInstead and mergeInstead are both probably misnomer.
>
> Let me take this part back.  After all, I do not think I would
> design the mechanism to implement an alternative logic that decides
> when it is safe to allow the update of the ref and to reflect the
> changes to the working tree, and that actually does the checkout to
> the working tree by using a new value like mergeInstead.  So we
> would only need a single name, and updateInstead is not too bad.
> ...
> The mechanism I would employ when doing an alternative logic,
> possibly looser one but does not necessarily so, would be to have a
> hook script "push-to-checkout".  When denyCurrentBranch is set to
> updateInstead, if there is no such hook, the "working tree has to be
> absolutely clean and we would do a 'read-tree -m -u $old $new'
> (which is the same as 'reset --hard $new' under the precondition)"
> you implemented will be used as the "logic that decides when it is
> safe, and that does the checkout to the working tree".  When the
> "push-to-checkout" hook exists, however, we just invoke that hook
> with $new as argument, and it can decide when it is safe in whatever
> way it chooses to, and it can checkout the $new to the working tree
> in whatever way it wants.

So here comes a two-patch series on top of your series (with the test update I sent earlier). As I never do "push to deploy" that requires no changes to the working tree or to the index, while I have seem myself in a situation where I have to emulate a "git pull" with a "git push" in the opposite direction (and work it around if the target of the 'git pull' I wanted to do were the current branch, by first pushing into a throw-away branch, because of denyCurrent), I could imagine myself using this variant. Having said that, this is primarily so that I do not want to forget and discard the brain cycles we spent discussing this to the waste, more than that I cannot wait to use this feature myself ;-)

The first one here is a pure refactoring. The second one is the real fun.

-- >8 --
Subject: [PATCH 1/2] receive-pack: refactor updateInstead codepath

Keep the "there is nothing to update in a bare repository", "when the check and update process runs, here are the GIT_DIR and GIT_WORK_TREE" logic, which will be common regardless of how the decision to update and the actual update are done, in the original update_worktree() function, and split out the "working tree and the index must match the original HEAD exactly" and "use two-way read-tree to update the working tree" into a new push_to_deploy() helper function. This will allow customizing the logic more cleanly and easily.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/receive-pack.c | 53 ++++++++++++++++++++++++++------------------------
 1 file changed, 28 insertions(+), 25 deletions(-)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c047418..11800cd 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -733,7 +733,9 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
 	return 0;
 }
 
-static const char *update_worktree(unsigned char *sha1)
+static const char *push_to_deploy(unsigned char *sha1,
+				  struct argv_array *env,
+				  const char *work_tree)
 {
 	const char *update_refresh[] = {
 		"update-index", "-q", "--ignore-submodules", "--refresh", NULL
@@ -748,69 +750,70 @@ static const char *update_worktree(unsigned char *sha1)
 	const char *read_tree[] = {
 		"read-tree", "-u", "-m", NULL, NULL
 	};
-	const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
-	struct argv_array env = ARGV_ARRAY_INIT;
 	struct child_process child = CHILD_PROCESS_INIT;
 
-	if (is_bare_repository())
-		return "denyCurrentBranch = updateInstead needs a worktree";
-
-	argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
-
 	child.argv = update_refresh;
-	child.env = env.argv;
+	child.env = env->argv;
 	child.dir = work_tree;
 	child.no_stdin = 1;
 	child.stdout_to_stderr = 1;
 	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
+	if (run_command(&child))
 		return "Up-to-date check failed";
-	}
 
 	/* run_command() does not clean up completely; reinitialize */
 	child_process_init(&child);
 	child.argv = diff_files;
-	child.env = env.argv;
+	child.env = env->argv;
 	child.dir = work_tree;
 	child.no_stdin = 1;
 	child.stdout_to_stderr = 1;
 	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
+	if (run_command(&child))
 		return "Working directory has unstaged changes";
-	}
 
 	child_process_init(&child);
 	child.argv = diff_index;
-	child.env = env.argv;
+	child.env = env->argv;
 	child.no_stdin = 1;
 	child.no_stdout = 1;
 	child.stdout_to_stderr = 0;
 	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
+	if (run_command(&child))
 		return "Working directory has staged changes";
-	}
 
 	read_tree[3] = sha1_to_hex(sha1);
 	child_process_init(&child);
 	child.argv = read_tree;
-	child.env = env.argv;
+	child.env = env->argv;
 	child.dir = work_tree;
 	child.no_stdin = 1;
 	child.no_stdout = 1;
 	child.stdout_to_stderr = 0;
 	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
+	if (run_command(&child))
 		return "Could not update working tree to new HEAD";
-	}
 
-	argv_array_clear(&env);
 	return NULL;
 }
 
+static const char *update_worktree(unsigned char *sha1)
+{
+	const char *retval;
+	const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
+	struct argv_array env = ARGV_ARRAY_INIT;
+
+	if (is_bare_repository())
+		return "denyCurrentBranch = updateInstead needs a worktree";
+
+	argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
+
+	retval = push_to_deploy(sha1, &env, work_tree);
+
+	argv_array_clear(&env);
+	return retval;
+}
+
 static const char *update(struct command *cmd, struct shallow_info *si)
 {
 	const char *name = cmd->ref_name;
-- 
2.2.0-141-gd3f4719
Previous: Junio C HamanoNext: Junio C Hamano
Message 28 of 71 in “Support updating working trees when pushing into non-bare repos”
  1. 0/2 Support updating working trees when pushing into non-bare reposJohannes Schindelin, Nov 7, 2014
  2. 1/2 Add a few more values for receive.denyCurrentBranchJohannes Schindelin, Nov 7, 2014
  3. Junio C HamanoNov 7, 2014
  4. Johannes SchindelinNov 7, 2014
  5. Johannes SchindelinNov 10, 2014
  6. Junio C HamanoNov 10, 2014
  7. Johannes SchindelinNov 12, 2014
  8. Junio C HamanoNov 12, 2014
  9. Jeff KingNov 8, 2014
  10. brian m. carlsonNov 8, 2014
  11. Johannes SchindelinNov 10, 2014
  12. 2/2 Let deny.currentBranch=updateInstead ignore submodulesJohannes Schindelin, Nov 7, 2014
  13. Junio C HamanoNov 7, 2014
  14. Jens LehmannNov 9, 2014
  15. Johannes SchindelinNov 10, 2014
  16. Johannes SchindelinNov 10, 2014
  17. Junio C HamanoNov 10, 2014
  18. Junio C HamanoNov 10, 2014
  19. Johannes SchindelinNov 12, 2014
  20. Junio C HamanoNov 12, 2014
  21. Johannes SchindelinNov 13, 2014
  22. Johannes SchindelinNov 13, 2014
  23. Junio C HamanoNov 13, 2014
  24. Johannes SchindelinNov 13, 2014
  25. Junio C HamanoNov 13, 2014
  26. Junio C HamanoNov 13, 2014
  27. Junio C HamanoNov 14, 2014
  28. Junio C HamanoDec 2, 2014
  29. 2/2 receive-pack: support push-to-checkout hookJunio C Hamano, Dec 2, 2014
  30. Johannes SchindelinDec 2, 2014
  31. Michael J GruberDec 2, 2014
  32. Johannes SchindelinDec 2, 2014
  33. Junio C HamanoDec 2, 2014
  34. Johannes SchindelinDec 2, 2014
  35. Junio C HamanoDec 2, 2014
  36. Johannes SchindelinDec 2, 2014
  37. Junio C HamanoDec 2, 2014
  38. Junio C HamanoNov 13, 2014
  39. Johannes SchindelinNov 12, 2014
  40. 0/2 Support updating working trees when pushing into non-bare reposJohannes Schindelin, Nov 10, 2014
  41. 0/1 Support updating working trees when pushing into non-bare reposJohannes Schindelin, Nov 13, 2014
  42. 1/1 Add another option for receive.denyCurrentBranchJohannes Schindelin, Nov 13, 2014
  43. Junio C HamanoNov 13, 2014
  44. Johannes SchindelinNov 13, 2014
  45. Junio C HamanoNov 13, 2014
  46. Junio C HamanoNov 13, 2014
  47. Johannes SchindelinNov 13, 2014
  48. Support updating working trees when pushing into non-bare reposJohannes Schindelin, Nov 26, 2014
  49. Add another option for receive.denyCurrentBranchJohannes Schindelin, Nov 26, 2014
  50. Junio C HamanoNov 26, 2014
  51. Support updating working trees when pushing into non-bare reposJohannes Schindelin, Nov 26, 2014
  52. Add another option for receive.denyCurrentBranchJohannes Schindelin, Nov 26, 2014
  53. Junio C HamanoDec 1, 2014
  54. Johannes SchindelinDec 1, 2014
  55. Junio C HamanoDec 1, 2014
  56. Junio C HamanoDec 2, 2014
  57. Johannes SchindelinDec 2, 2014
  58. Junio C HamanoDec 2, 2014
  59. Johannes SchindelinDec 2, 2014
  60. Junio C HamanoDec 2, 2014
  61. 1/2 Clean stale environment pointer in finish_command()Johannes Schindelin, Nov 10, 2014
  62. Johannes SchindelinNov 10, 2014
  63. Jeff KingNov 11, 2014
  64. Junio C HamanoNov 11, 2014
  65. Johannes SchindelinNov 12, 2014
  66. Jeff KingNov 12, 2014
  67. Jeff KingNov 12, 2014
  68. Junio C HamanoNov 12, 2014
  69. Junio C HamanoNov 10, 2014
  70. Jeff KingNov 11, 2014
  71. 2/2 Add a few more options for receive.denyCurrentBranchJohannes Schindelin, Nov 10, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.