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

[PATCH 1/2] Introduce receive.guardCurrentBranch

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 23, 2008, 20:43 UTC
Message-ID
<alpine.LSU.1.00.0803232142460.4353@racer.site>

Setting this config variable to "true" makes git-receive-pack refuse to update whatever happens to be the current branch.

This option can be used to avoid havoc in a non-bare repository into which somebody pushes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	I thought about this a while (see also
	http://thread.gmane.org/gmane.comp.version-control.git/66490),
	and I think it is time to push for this change.
	On the one hand, of course, it is nice to have so many users
	that not all of them know the Git source intimately.  On the
	other hand, we will have to introduce many more safeguards
	like this now.  Sigh...
	Maybe this is even 1.5.5 material.  I'm undecided.
 Documentation/config.txt           |    5 +++++
 Documentation/git-receive-pack.txt |    3 +++
 receive-pack.c                     |   18 ++++++++++++++++++
 t/t5400-send-pack.sh               |   13 +++++++++++++
 4 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5df8ea9..efde54d 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1006,6 +1006,11 @@ receive.denyNonFastForwards::
 	even if that push is forced. This configuration variable is
 	set when initializing a shared repository.
 
+receive.guardCurrentBranch::
+	If set to true, git-receive-pack will deny to update the ref that
+	HEAD points to, if HEAD is not detached.  This configuration
+	variable is set when initializing a non-bare repository.
+
 transfer.unpackLimit::
 	When `fetch.unpackLimit` or `receive.unpackLimit` are
 	not set, the value of this variable is used instead.
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 4111434..0c82af9 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -32,6 +32,9 @@ git-receive-pack honours the receive.denyNonFastForwards config
 option, which tells it if updates to a ref should be denied if they
 are not fast-forwards.
 
+git-receive-pack honors the receive.guardCurrentBranch config options,
+which tells it if it is okay to update the branch HEAD points to.
+
 OPTIONS
 -------
 <directory>::
diff --git a/receive-pack.c b/receive-pack.c
index 828d490..6423c7c 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -15,6 +15,7 @@ static int receive_unpack_limit = -1;
 static int transfer_unpack_limit = -1;
 static int unpack_limit = 100;
 static int report_status;
+static char *guard_current_branch;
 
 static char capabilities[] = " report-status delete-refs ";
 static int capabilities_sent;
@@ -41,6 +42,19 @@ static int receive_pack_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (strcmp(var, "receive.guardhead") == 0) {
+		guard_current_branch = NULL;
+		if (git_config_bool(var, value)) {
+			unsigned char sha1[20];
+			int flag;
+			const char *head = resolve_ref("HEAD", sha1, 0, &flag);
+			if (flag & REF_ISSYMREF)
+				guard_current_branch = xstrdup(head);
+		}
+
+		return 0;
+	}
+
 	return git_default_config(var, value);
 }
 
@@ -183,6 +197,10 @@ static const char *update(struct command *cmd)
 		      "but I can't find it!", sha1_to_hex(new_sha1));
 		return "bad pack";
 	}
+	if (guard_current_branch && !strcmp(name, guard_current_branch)) {
+		error("refusing to update current branch: '%s'", name);
+		return "current branch";
+	}
 	if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
 	    !is_null_sha1(old_sha1) &&
 	    !prefixcmp(name, "refs/heads/")) {
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 2b6b6e3..af8d5a3 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -171,4 +171,17 @@ test_expect_success \
 	rewound_push_succeeded
 '
 
+test_expect_success 'receive.guardCurrentBranch' '
+
+	rewound_push_setup &&
+	(cd ../parent &&
+	 git config receive.guardCurrentBranch true) &&
+	test_must_fail git-send-pack ../parent/.git refs/heads/master &&
+	rewound_push_failed &&
+	(cd ../parent &&
+	 git config receive.guardCurrentBranch false) &&
+	git-send-pack ../parent/.git +refs/heads/*:refs/heads/* &&
+	rewound_push_succeeded
+'
+
 test_done
-- 
1.5.5.rc1.174.g591a9
Next: Johannes Schindelin
Message 1 of 11 in “Introduce receive.guardCurrentBranch”
  1. 1/2 Introduce receive.guardCurrentBranchJohannes Schindelin, Mar 23, 2008
  2. 2/2 git-init: set receive.guardCurrentBranch = true for non-bare repositoriesJohannes Schindelin, Mar 23, 2008
  3. Junio C HamanoMar 24, 2008
  4. Johannes SchindelinMar 24, 2008
  5. Junio C HamanoMar 24, 2008
  6. Johannes SchindelinMar 24, 2008
  7. Daniel BarkalowMar 24, 2008
  8. Johannes SchindelinMar 24, 2008
  9. Miklos VajnaMar 24, 2008
  10. Johannes SchindelinMar 24, 2008
  11. Miklos VajnaMar 24, 2008

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.