files-backend: extract out `create_symref_lock()`

The function `create_symref_locked()` creates a symref by creating a '<symref>.lock' file and then committing the symref lock, which creates the final symref. Extract the early half of `create_symref_locked()` into a new helper function `create_symref_lock()`. Because the name of the new function is too similar to the original, rename the original to `create_and_commit_symref()` to avoid confusion. The new function `create_symref_locked()` can be used to create the symref lock in a separate step from that of committing it. This allows to add transactional support for symrefs, where the lock would be created in the preparation step and the lock would be committed in the finish step. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karthik Nayak committed May 7, 2024 at 14:58 UTC 57d0b1e2ea7d133c0ff2461e99c2847fe4ae55e2
1 file changed +37 -14
refs/files-backend.c
+37 -14
@@ -1920,27 +1920,49 @@ static void update_symref_reflog(struct files_ref_store *refs,
1920 }
1921 }
1922
1923 -static int create_symref_locked(struct files_ref_store *refs,
1924 - struct ref_lock *lock, const char *refname,
1925 - const char *target, const char *logmsg)
1923 +static int create_symref_lock(struct files_ref_store *refs,
1924 + struct ref_lock *lock, const char *refname,
1925 + const char *target, struct strbuf *err)
1926 {
1927 + if (!fdopen_lock_file(&lock->lk, "w")) {
1928 + strbuf_addf(err, "unable to fdopen %s: %s",
1929 + get_lock_file_path(&lock->lk), strerror(errno));
1930 + return -1;
1931 + }
1932 +
1933 + if (fprintf(get_lock_file_fp(&lock->lk), "ref: %s\n", target) < 0) {
1934 + strbuf_addf(err, "unable to write to %s: %s",
1935 + get_lock_file_path(&lock->lk), strerror(errno));
1936 + return -1;
1937 + }
1938 +
1939 + return 0;
1940 +}
1941 +
1942 +static int create_and_commit_symref(struct files_ref_store *refs,
1943 + struct ref_lock *lock, const char *refname,
1944 + const char *target, const char *logmsg)
1945 +{
1946 + struct strbuf err = STRBUF_INIT;
1947 + int ret;
1948 +
1949 if (prefer_symlink_refs && !create_ref_symlink(lock, target)) {
1950 update_symref_reflog(refs, lock, refname, target, logmsg);
1951 return 0;
1952 }
1953
1932 - if (!fdopen_lock_file(&lock->lk, "w"))
1933 - return error("unable to fdopen %s: %s",
1934 - get_lock_file_path(&lock->lk), strerror(errno));
1954 + ret = create_symref_lock(refs, lock, refname, target, &err);
1955 + if (!ret) {
1956 + update_symref_reflog(refs, lock, refname, target, logmsg);
1957
1936 - update_symref_reflog(refs, lock, refname, target, logmsg);
1958 + if (commit_ref(lock) < 0)
1959 + return error("unable to write symref for %s: %s", refname,
1960 + strerror(errno));
1961 + } else {
1962 + return error("%s", err.buf);
1963 + }
1964
1938 - /* no error check; commit_ref will check ferror */
1939 - fprintf(get_lock_file_fp(&lock->lk), "ref: %s\n", target);
1940 - if (commit_ref(lock) < 0)
1941 - return error("unable to write symref for %s: %s", refname,
1942 - strerror(errno));
1943 - return 0;
1965 + return ret;
1966 }
1967
1968 static int files_create_symref(struct ref_store *ref_store,
@@ -1960,7 +1982,8 @@ static int files_create_symref(struct ref_store *ref_store,
1982 return -1;
1983 }
1984
1963 - ret = create_symref_locked(refs, lock, refname, target, logmsg);
1985 + ret = create_and_commit_symref(refs, lock, refname, target, logmsg);
1986 +
1987 unlock_ref(lock);
1988 return ret;
1989 }