Skip to content

Commit ac6c561

Browse files
rappazzogitster
authored andcommitted
worktree: add top-level worktree.c
worktree.c contains functions to work with and get information from worktrees. This introduction moves functions related to worktrees from branch.c into worktree.c Signed-off-by: Michael Rappazzo <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8d530c4 commit ac6c561

File tree

6 files changed

+97
-87
lines changed

6 files changed

+97
-87
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ LIB_OBJS += version.o
807807
LIB_OBJS += versioncmp.o
808808
LIB_OBJS += walker.o
809809
LIB_OBJS += wildmatch.o
810+
LIB_OBJS += worktree.o
810811
LIB_OBJS += wrapper.o
811812
LIB_OBJS += write_or_die.o
812813
LIB_OBJS += ws.o

branch.c

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "refs.h"
55
#include "remote.h"
66
#include "commit.h"
7+
#include "worktree.h"
78

89
struct tracking {
910
struct refspec spec;
@@ -311,84 +312,6 @@ void remove_branch_state(void)
311312
unlink(git_path_squash_msg());
312313
}
313314

314-
static char *find_linked_symref(const char *symref, const char *branch,
315-
const char *id)
316-
{
317-
struct strbuf sb = STRBUF_INIT;
318-
struct strbuf path = STRBUF_INIT;
319-
struct strbuf gitdir = STRBUF_INIT;
320-
char *existing = NULL;
321-
322-
/*
323-
* $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside
324-
* $GIT_DIR so resolve_ref_unsafe() won't work (it uses
325-
* git_path). Parse the ref ourselves.
326-
*/
327-
if (id)
328-
strbuf_addf(&path, "%s/worktrees/%s/%s", get_git_common_dir(), id, symref);
329-
else
330-
strbuf_addf(&path, "%s/%s", get_git_common_dir(), symref);
331-
332-
if (!strbuf_readlink(&sb, path.buf, 0)) {
333-
if (!starts_with(sb.buf, "refs/") ||
334-
check_refname_format(sb.buf, 0))
335-
goto done;
336-
} else if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
337-
starts_with(sb.buf, "ref:")) {
338-
strbuf_remove(&sb, 0, strlen("ref:"));
339-
strbuf_trim(&sb);
340-
} else
341-
goto done;
342-
if (strcmp(sb.buf, branch))
343-
goto done;
344-
if (id) {
345-
strbuf_reset(&path);
346-
strbuf_addf(&path, "%s/worktrees/%s/gitdir", get_git_common_dir(), id);
347-
if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
348-
goto done;
349-
strbuf_rtrim(&gitdir);
350-
} else
351-
strbuf_addstr(&gitdir, get_git_common_dir());
352-
strbuf_strip_suffix(&gitdir, ".git");
353-
354-
existing = strbuf_detach(&gitdir, NULL);
355-
done:
356-
strbuf_release(&path);
357-
strbuf_release(&sb);
358-
strbuf_release(&gitdir);
359-
360-
return existing;
361-
}
362-
363-
char *find_shared_symref(const char *symref, const char *target)
364-
{
365-
struct strbuf path = STRBUF_INIT;
366-
DIR *dir;
367-
struct dirent *d;
368-
char *existing;
369-
370-
if ((existing = find_linked_symref(symref, target, NULL)))
371-
return existing;
372-
373-
strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
374-
dir = opendir(path.buf);
375-
strbuf_release(&path);
376-
if (!dir)
377-
return NULL;
378-
379-
while ((d = readdir(dir)) != NULL) {
380-
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
381-
continue;
382-
existing = find_linked_symref(symref, target, d->d_name);
383-
if (existing)
384-
goto done;
385-
}
386-
done:
387-
closedir(dir);
388-
389-
return existing;
390-
}
391-
392315
void die_if_checked_out(const char *branch)
393316
{
394317
char *existing;

branch.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,4 @@ extern int read_branch_desc(struct strbuf *, const char *branch_name);
5959
*/
6060
extern void die_if_checked_out(const char *branch);
6161

62-
/*
63-
* Check if a per-worktree symref points to a ref in the main worktree
64-
* or any linked worktree, and return the path to the exising worktree
65-
* if it is. Returns NULL if there is no existing ref. The caller is
66-
* responsible for freeing the returned path.
67-
*/
68-
extern char *find_shared_symref(const char *symref, const char *target);
69-
7062
#endif

builtin/notes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "string-list.h"
2020
#include "notes-merge.h"
2121
#include "notes-utils.h"
22-
#include "branch.h"
22+
#include "worktree.h"
2323

2424
static const char * const git_notes_usage[] = {
2525
N_("git notes [--ref <notes-ref>] [list [<object>]]"),

worktree.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "cache.h"
2+
#include "refs.h"
3+
#include "strbuf.h"
4+
#include "worktree.h"
5+
6+
static char *find_linked_symref(const char *symref, const char *branch,
7+
const char *id)
8+
{
9+
struct strbuf sb = STRBUF_INIT;
10+
struct strbuf path = STRBUF_INIT;
11+
struct strbuf gitdir = STRBUF_INIT;
12+
char *existing = NULL;
13+
14+
/*
15+
* $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside
16+
* $GIT_DIR so resolve_ref_unsafe() won't work (it uses
17+
* git_path). Parse the ref ourselves.
18+
*/
19+
if (id)
20+
strbuf_addf(&path, "%s/worktrees/%s/%s", get_git_common_dir(), id, symref);
21+
else
22+
strbuf_addf(&path, "%s/%s", get_git_common_dir(), symref);
23+
24+
if (!strbuf_readlink(&sb, path.buf, 0)) {
25+
if (!starts_with(sb.buf, "refs/") ||
26+
check_refname_format(sb.buf, 0))
27+
goto done;
28+
} else if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
29+
starts_with(sb.buf, "ref:")) {
30+
strbuf_remove(&sb, 0, strlen("ref:"));
31+
strbuf_trim(&sb);
32+
} else
33+
goto done;
34+
if (strcmp(sb.buf, branch))
35+
goto done;
36+
if (id) {
37+
strbuf_reset(&path);
38+
strbuf_addf(&path, "%s/worktrees/%s/gitdir", get_git_common_dir(), id);
39+
if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
40+
goto done;
41+
strbuf_rtrim(&gitdir);
42+
} else
43+
strbuf_addstr(&gitdir, get_git_common_dir());
44+
strbuf_strip_suffix(&gitdir, ".git");
45+
46+
existing = strbuf_detach(&gitdir, NULL);
47+
done:
48+
strbuf_release(&path);
49+
strbuf_release(&sb);
50+
strbuf_release(&gitdir);
51+
52+
return existing;
53+
}
54+
55+
char *find_shared_symref(const char *symref, const char *target)
56+
{
57+
struct strbuf path = STRBUF_INIT;
58+
DIR *dir;
59+
struct dirent *d;
60+
char *existing;
61+
62+
if ((existing = find_linked_symref(symref, target, NULL)))
63+
return existing;
64+
65+
strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
66+
dir = opendir(path.buf);
67+
strbuf_release(&path);
68+
if (!dir)
69+
return NULL;
70+
71+
while ((d = readdir(dir)) != NULL) {
72+
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
73+
continue;
74+
existing = find_linked_symref(symref, target, d->d_name);
75+
if (existing)
76+
goto done;
77+
}
78+
done:
79+
closedir(dir);
80+
81+
return existing;
82+
}

worktree.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef WORKTREE_H
2+
#define WORKTREE_H
3+
4+
/*
5+
* Check if a per-worktree symref points to a ref in the main worktree
6+
* or any linked worktree, and return the path to the exising worktree
7+
* if it is. Returns NULL if there is no existing ref. The caller is
8+
* responsible for freeing the returned path.
9+
*/
10+
extern char *find_shared_symref(const char *symref, const char *target);
11+
12+
#endif

0 commit comments

Comments
 (0)