git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] fix git branch -m in presence of cross devices
@ 2010-07-07  7:47 Pierre Habouzit
  0 siblings, 0 replies; only message in thread
From: Pierre Habouzit @ 2010-07-07  7:47 UTC (permalink / raw)
  To: Git ML; +Cc: Junio C Hamano

When you have for example a bare repository stored on NFS, and that you
create new workdirs locally (using contrib's git-new-workdir), logs/refs
is a symlink to a different device. Hence when the reflogs are renamed,
all must happen below logs/refs or one gets cross device rename errors
like:

  git branch -m foo
  error: unable to move logfile logs/refs/heads/master to tmp-renamed-log: Invalid cross-device link
  fatal: Branch rename failed

The fix is hence to use logs/refs/.tmp-renamed-log as a temporary log
name, instead of just tmp-renamed-log.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 refs.c |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/refs.c b/refs.c
index 6f486ae..b540067 100644
--- a/refs.c
+++ b/refs.c
@@ -1090,6 +1090,15 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 	return ret;
 }
 
+/*
+ * People using contrib's git-new-workdir have .git/logs/refs ->
+ * /some/other/path/.git/logs/refs, and that may live on another device.
+ *
+ * IOW, to avoid cross device rename errors, the temporary renamed log must
+ * live into logs/refs.
+ */
+#define TMP_RENAMED_LOG  "logs/refs/.tmp-renamed-log"
+
 int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 {
 	static const char renamed_ref[] = "RENAMED-REF";
@@ -1123,8 +1132,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 	if (write_ref_sha1(lock, orig_sha1, logmsg))
 		return error("unable to save current sha1 in %s", renamed_ref);
 
-	if (log && rename(git_path("logs/%s", oldref), git_path("tmp-renamed-log")))
-		return error("unable to move logfile logs/%s to tmp-renamed-log: %s",
+	if (log && rename(git_path("logs/%s", oldref), git_path(TMP_RENAMED_LOG)))
+		return error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s",
 			oldref, strerror(errno));
 
 	if (delete_ref(oldref, orig_sha1, REF_NODEREF)) {
@@ -1150,7 +1159,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 	}
 
  retry:
-	if (log && rename(git_path("tmp-renamed-log"), git_path("logs/%s", newref))) {
+	if (log && rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newref))) {
 		if (errno==EISDIR || errno==ENOTDIR) {
 			/*
 			 * rename(a, b) when b is an existing
@@ -1163,7 +1172,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 			}
 			goto retry;
 		} else {
-			error("unable to move logfile tmp-renamed-log to logs/%s: %s",
+			error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
 				newref, strerror(errno));
 			goto rollback;
 		}
@@ -1203,8 +1212,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 		error("unable to restore logfile %s from %s: %s",
 			oldref, newref, strerror(errno));
 	if (!logmoved && log &&
-	    rename(git_path("tmp-renamed-log"), git_path("logs/%s", oldref)))
-		error("unable to restore logfile %s from tmp-renamed-log: %s",
+	    rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldref)))
+		error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
 			oldref, strerror(errno));
 
 	return 1;
-- 
1.7.2.rc1.212.g850a.dirty

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2010-07-07  7:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-07  7:47 [PATCH] fix git branch -m in presence of cross devices Pierre Habouzit

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).