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

[PATCH v4 32/32] Extract a function commit_lock_file_to()

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Sep 6, 2014, 07:50 UTC
Message-ID
<1409989846-22401-33-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<1409989846-22401-1-git-send-email-mhagger@alum.mit.edu>

commit_locked_index(), when writing to an alternate index file, duplicates (poorly) the code in commit_lock_file(). And anyway, it shouldn't have to know so much about the internal workings of lockfile objects. So extract a new function commit_lock_file_to() that does the work common to the two functions, and call it from both commit_lock_file() and commit_locked_index().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 Documentation/technical/api-lockfile.txt | 14 ++++++++++----
 cache.h                                  |  1 +
 lockfile.c                               | 30 ++++++++++++++++++------------
 read-cache.c                             | 13 +++----------
 4 files changed, 32 insertions(+), 26 deletions(-)
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index 2514559..3ee4299 100644
--- a/Documentation/technical/api-lockfile.txt
+++ b/Documentation/technical/api-lockfile.txt
@@ -73,6 +73,12 @@ commit_lock_file::
 	`commit_lock_file()` for a `lock_file` object that is not
 	currently locked.
 
+commit_lock_file_to::
+
+	Like `commit_lock_file()`, except that it takes an explicit
+	`path` argument to which the lockfile should be renamed. The
+	`path` must be on the same filesystem as the lock file.
+
 rollback_lock_file::
 
 	Take a pointer to the `struct lock_file` initialized
@@ -91,10 +97,10 @@ Because the structure is used in an `atexit(3)` handler, its
 storage has to stay throughout the life of the program.  It
 cannot be an auto variable allocated on the stack.
 
-Call `commit_lock_file()` or `rollback_lock_file()` when you are
-done writing to the file descriptor.  If you do not call either
-and simply `exit(3)` from the program, an `atexit(3)` handler
-will close and remove the lockfile.
+Call `commit_lock_file()`, `commit_lock_file_to()`, or
+`rollback_lock_file()` when you are done writing to the file
+descriptor. If you do not call either and simply `exit(3)` from the
+program, an `atexit(3)` handler will close and remove the lockfile.
 
 If you need to close the file descriptor you obtained from
 `hold_lock_file_for_update` function yourself, do so by calling
diff --git a/cache.h b/cache.h
index bea6296..cda91fc 100644
--- a/cache.h
+++ b/cache.h
@@ -589,6 +589,7 @@ extern void unable_to_lock_message(const char *path, int err,
 extern NORETURN void unable_to_lock_die(const char *path, int err);
 extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
 extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
+extern int commit_lock_file_to(struct lock_file *, const char *path);
 extern int commit_lock_file(struct lock_file *);
 extern int reopen_lock_file(struct lock_file *);
 extern void update_index_if_able(struct index_state *, struct lock_file *);
diff --git a/lockfile.c b/lockfile.c
index 4c6e720..e54d260 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -53,8 +53,9 @@
  * - Locked, lockfile closed (after close_lock_file()).  Same as the
  *   previous state, except that the lockfile is closed and fd is -1.
  *
- * - Unlocked (after commit_lock_file(), rollback_lock_file(), or a
- *   failed attempt to lock).  In this state:
+ * - Unlocked (after commit_lock_file(), commit_lock_file_to(),
+ *   rollback_lock_file(), or a failed attempt to lock).  In this
+ *   state:
  *   - active is unset
  *   - filename is the empty string (usually, though there are
  *     transitory states in which this condition doesn't hold)
@@ -277,24 +278,16 @@ int reopen_lock_file(struct lock_file *lk)
 	return lk->fd;
 }
 
-int commit_lock_file(struct lock_file *lk)
+int commit_lock_file_to(struct lock_file *lk, const char *path)
 {
-	static struct strbuf result_file = STRBUF_INIT;
 	int save_errno;
-	int err;
 
 	if (!lk->active)
 		die("BUG: attempt to commit unlocked object");
 
 	if (lk->fd >= 0 && close_lock_file(lk))
 		goto rollback;
-
-	/* remove ".lock": */
-	strbuf_add(&result_file, lk->filename.buf,
-		   lk->filename.len - LOCK_SUFFIX_LEN);
-	err = rename(lk->filename.buf, result_file.buf);
-	strbuf_reset(&result_file);
-	if (err)
+	if (rename(lk->filename.buf, path))
 		goto rollback;
 	lk->active = 0;
 	strbuf_reset(&lk->filename);
@@ -307,6 +300,19 @@ rollback:
 	return -1;
 }
 
+int commit_lock_file(struct lock_file *lk)
+{
+	static struct strbuf result_file = STRBUF_INIT;
+	int err;
+
+	/* remove ".lock": */
+	strbuf_add(&result_file, lk->filename.buf,
+		   lk->filename.len - LOCK_SUFFIX_LEN);
+	err = commit_lock_file_to(lk, result_file.buf);
+	strbuf_reset(&result_file);
+	return err;
+}
+
 int hold_locked_index(struct lock_file *lk, int die_on_error)
 {
 	return hold_lock_file_for_update(lk, get_index_file(),
diff --git a/read-cache.c b/read-cache.c
index 158241d..11b80a0 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2023,17 +2023,10 @@ void set_alternate_index_output(const char *name)
 
 static int commit_locked_index(struct lock_file *lk)
 {
-	if (alternate_index_output) {
-		if (lk->fd >= 0 && close_lock_file(lk))
-			return -1;
-		if (rename(lk->filename.buf, alternate_index_output))
-			return -1;
-		lk->active = 0;
-		strbuf_reset(&lk->filename);
-		return 0;
-	} else {
+	if (alternate_index_output)
+		return commit_lock_file_to(lk, alternate_index_output);
+	else
 		return commit_lock_file(lk);
-	}
 }
 
 static int do_write_locked_index(struct index_state *istate, struct lock_file *lock,
-- 
2.1.0
Previous: Michael HaggertyNext: Torsten Bögershausen
Message 54 of 66 in “Lockfile correctness and refactoring”
  1. 00/32 Lockfile correctness and refactoringMichael Haggerty, Sep 6, 2014
  2. 01/32 unable_to_lock_die(): rename function from unable_to_lock_index_die()Michael Haggerty, Sep 6, 2014
  3. 02/32 api-lockfile: expand the documentationMichael Haggerty, Sep 6, 2014
  4. Junio C HamanoSep 9, 2014
  5. 03/32 rollback_lock_file(): do not clear filename redundantlyMichael Haggerty, Sep 6, 2014
  6. Ronnie SahlbergSep 11, 2014
  7. 04/32 rollback_lock_file(): exit early if lock is not activeMichael Haggerty, Sep 6, 2014
  8. Ronnie SahlbergSep 11, 2014
  9. 05/32 rollback_lock_file(): set fd to -1Michael Haggerty, Sep 6, 2014
  10. 06/32 lockfile: unlock file if lockfile permissions cannot be adjustedMichael Haggerty, Sep 6, 2014
  11. Junio C HamanoSep 9, 2014
  12. Michael HaggertySep 12, 2014
  13. 07/32 hold_lock_file_for_append(): release lock on errorsMichael Haggerty, Sep 6, 2014
  14. Junio C HamanoSep 9, 2014
  15. Michael HaggertySep 12, 2014
  16. 08/32 lock_file(): always add lock_file object to lock_file_listMichael Haggerty, Sep 6, 2014
  17. 09/32 lockfile.c: document the various states of lock_file objectsMichael Haggerty, Sep 6, 2014
  18. Ronnie SahlbergSep 11, 2014
  19. 10/32 cache.h: define constants LOCK_SUFFIX and LOCK_SUFFIX_LENMichael Haggerty, Sep 6, 2014
  20. Ronnie SahlbergSep 11, 2014
  21. Michael HaggertySep 12, 2014
  22. Ronnie SahlbergSep 11, 2014
  23. Michael HaggertySep 12, 2014
  24. Ronnie SahlbergSep 12, 2014
  25. 11/32 delete_ref_loose(): don't muck around in the lock_file's filenameMichael Haggerty, Sep 6, 2014
  26. Johannes SixtSep 13, 2014
  27. Michael HaggertySep 14, 2014
  28. Michael HaggertySep 14, 2014
  29. Johannes SixtSep 14, 2014
  30. 12/32 prepare_index(): declare return value to be (const char *)Michael Haggerty, Sep 6, 2014
  31. 13/32 write_packed_entry_fn(): convert cb_data into a (const int *)Michael Haggerty, Sep 6, 2014
  32. Ronnie SahlbergSep 11, 2014
  33. 14/32 lock_file(): exit early if lockfile cannot be openedMichael Haggerty, Sep 6, 2014
  34. Ronnie SahlbergSep 11, 2014
  35. 15/32 remove_lock_file(): call rollback_lock_file()Michael Haggerty, Sep 6, 2014
  36. 16/32 commit_lock_file(): inline temporary variableMichael Haggerty, Sep 6, 2014
  37. 17/32 commit_lock_file(): die() if called for unlocked lockfile objectMichael Haggerty, Sep 6, 2014
  38. 18/32 commit_lock_file(): if close fails, roll backMichael Haggerty, Sep 6, 2014
  39. 19/32 commit_lock_file(): rollback lock file on failure to renameMichael Haggerty, Sep 6, 2014
  40. Jeff KingSep 10, 2014
  41. Duy NguyenSep 10, 2014
  42. 20/32 api-lockfile: document edge casesMichael Haggerty, Sep 6, 2014
  43. 21/32 dump_marks(): remove a redundant call to rollback_lock_file()Michael Haggerty, Sep 6, 2014
  44. 22/32 git_config_set_multivar_in_file(): avoid call to rollback_lock_file()Michael Haggerty, Sep 6, 2014
  45. 23/32 lockfile: avoid transitory invalid statesMichael Haggerty, Sep 6, 2014
  46. 24/32 struct lock_file: declare some fields volatileMichael Haggerty, Sep 6, 2014
  47. 25/32 try_merge_strategy(): remove redundant lock_file allocationMichael Haggerty, Sep 6, 2014
  48. 26/32 try_merge_strategy(): use a statically-allocated lock_file objectMichael Haggerty, Sep 6, 2014
  49. 27/32 commit_lock_file(): use a strbuf to manage temporary spaceMichael Haggerty, Sep 6, 2014
  50. 28/32 Change lock_file::filename into a strbufMichael Haggerty, Sep 6, 2014
  51. 29/32 resolve_symlink(): use a strbuf for internal scratch spaceMichael Haggerty, Sep 6, 2014
  52. 30/32 resolve_symlink(): take a strbuf parameterMichael Haggerty, Sep 6, 2014
  53. 31/32 trim_last_path_elm(): replace last_path_elm()Michael Haggerty, Sep 6, 2014
  54. 32/32 Extract a function commit_lock_file_to()Michael Haggerty, Sep 6, 2014
  55. Torsten BögershausenSep 7, 2014
  56. Michael HaggertySep 12, 2014
  57. Junio C HamanoSep 8, 2014
  58. Jeff KingSep 10, 2014
  59. Duy NguyenSep 10, 2014
  60. Jeff KingSep 10, 2014
  61. Junio C HamanoSep 10, 2014
  62. Jeff KingSep 10, 2014
  63. Michael HaggertySep 12, 2014
  64. Michael HaggertySep 12, 2014
  65. Michael HaggertySep 12, 2014
  66. Jeff KingSep 13, 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.