Skip to content

Commit 19cb1fc

Browse files
committed
Merge branch 'ds/scalar-updates'
Scalar updates. * ds/scalar-updates: scalar reconfigure: help users remove buggy repos setup: add discover_git_directory_reason() scalar: add --[no-]src option
2 parents a59dbae + f9a547d commit 19cb1fc

File tree

5 files changed

+115
-44
lines changed

5 files changed

+115
-44
lines changed

Documentation/scalar.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ scalar - A tool for managing large Git repositories
88
SYNOPSIS
99
--------
1010
[verse]
11-
scalar clone [--single-branch] [--branch <main-branch>] [--full-clone] <url> [<enlistment>]
11+
scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]
12+
[--[no-]src] <url> [<enlistment>]
1213
scalar list
1314
scalar register [<enlistment>]
1415
scalar unregister [<enlistment>]
@@ -80,6 +81,11 @@ remote-tracking branch for the branch this option was used for the initial
8081
cloning. If the HEAD at the remote did not point at any branch when
8182
`--single-branch` clone was made, no remote-tracking branch is created.
8283

84+
--[no-]src::
85+
By default, `scalar clone` places the cloned repository within a
86+
`<entlistment>/src` directory. Use `--no-src` to place the cloned
87+
repository directly in the `<enlistment>` directory.
88+
8389
--[no-]full-clone::
8490
A sparse-checkout is initialized by default. This behavior can be
8591
turned off via `--full-clone`.

scalar.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ static int cmd_clone(int argc, const char **argv)
409409
{
410410
const char *branch = NULL;
411411
int full_clone = 0, single_branch = 0, show_progress = isatty(2);
412+
int src = 1;
412413
struct option clone_options[] = {
413414
OPT_STRING('b', "branch", &branch, N_("<branch>"),
414415
N_("branch to checkout after clone")),
@@ -417,10 +418,13 @@ static int cmd_clone(int argc, const char **argv)
417418
OPT_BOOL(0, "single-branch", &single_branch,
418419
N_("only download metadata for the branch that will "
419420
"be checked out")),
421+
OPT_BOOL(0, "src", &src,
422+
N_("create repository within 'src' directory")),
420423
OPT_END(),
421424
};
422425
const char * const clone_usage[] = {
423-
N_("scalar clone [<options>] [--] <repo> [<dir>]"),
426+
N_("scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n"
427+
"\t[--[no-]src] <url> [<enlistment>]"),
424428
NULL
425429
};
426430
const char *url;
@@ -456,7 +460,10 @@ static int cmd_clone(int argc, const char **argv)
456460
if (is_directory(enlistment))
457461
die(_("directory '%s' exists already"), enlistment);
458462

459-
dir = xstrfmt("%s/src", enlistment);
463+
if (src)
464+
dir = xstrfmt("%s/src", enlistment);
465+
else
466+
dir = xstrdup(enlistment);
460467

461468
strbuf_reset(&buf);
462469
if (branch)
@@ -657,6 +664,7 @@ static int cmd_reconfigure(int argc, const char **argv)
657664
git_config(get_scalar_repos, &scalar_repos);
658665

659666
for (i = 0; i < scalar_repos.nr; i++) {
667+
int succeeded = 0;
660668
const char *dir = scalar_repos.items[i].string;
661669

662670
strbuf_reset(&commondir);
@@ -667,30 +675,56 @@ static int cmd_reconfigure(int argc, const char **argv)
667675

668676
if (errno != ENOENT) {
669677
warning_errno(_("could not switch to '%s'"), dir);
670-
res = -1;
671-
continue;
678+
goto loop_end;
672679
}
673680

674681
strbuf_addstr(&buf, dir);
675682
if (remove_deleted_enlistment(&buf))
676-
res = error(_("could not remove stale "
677-
"scalar.repo '%s'"), dir);
678-
else
679-
warning(_("removing stale scalar.repo '%s'"),
683+
error(_("could not remove stale "
684+
"scalar.repo '%s'"), dir);
685+
else {
686+
warning(_("removed stale scalar.repo '%s'"),
680687
dir);
688+
succeeded = 1;
689+
}
681690
strbuf_release(&buf);
682-
} else if (discover_git_directory(&commondir, &gitdir) < 0) {
683-
warning_errno(_("git repository gone in '%s'"), dir);
684-
res = -1;
685-
} else {
686-
git_config_clear();
691+
goto loop_end;
692+
}
693+
694+
switch (discover_git_directory_reason(&commondir, &gitdir)) {
695+
case GIT_DIR_INVALID_OWNERSHIP:
696+
warning(_("repository at '%s' has different owner"), dir);
697+
goto loop_end;
698+
699+
case GIT_DIR_INVALID_GITFILE:
700+
case GIT_DIR_INVALID_FORMAT:
701+
warning(_("repository at '%s' has a format issue"), dir);
702+
goto loop_end;
703+
704+
case GIT_DIR_DISCOVERED:
705+
succeeded = 1;
706+
break;
707+
708+
default:
709+
warning(_("repository not found in '%s'"), dir);
710+
break;
711+
}
687712

688-
the_repository = &r;
689-
r.commondir = commondir.buf;
690-
r.gitdir = gitdir.buf;
713+
git_config_clear();
691714

692-
if (set_recommended_config(1) < 0)
693-
res = -1;
715+
the_repository = &r;
716+
r.commondir = commondir.buf;
717+
r.gitdir = gitdir.buf;
718+
719+
if (set_recommended_config(1) >= 0)
720+
succeeded = 1;
721+
722+
loop_end:
723+
if (!succeeded) {
724+
res = -1;
725+
warning(_("to unregister this repository from Scalar, run\n"
726+
"\tgit config --global --unset --fixed-value scalar.repo \"%s\""),
727+
dir);
694728
}
695729
}
696730

setup.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,19 +1221,6 @@ static const char *allowed_bare_repo_to_string(
12211221
return NULL;
12221222
}
12231223

1224-
enum discovery_result {
1225-
GIT_DIR_NONE = 0,
1226-
GIT_DIR_EXPLICIT,
1227-
GIT_DIR_DISCOVERED,
1228-
GIT_DIR_BARE,
1229-
/* these are errors */
1230-
GIT_DIR_HIT_CEILING = -1,
1231-
GIT_DIR_HIT_MOUNT_POINT = -2,
1232-
GIT_DIR_INVALID_GITFILE = -3,
1233-
GIT_DIR_INVALID_OWNERSHIP = -4,
1234-
GIT_DIR_DISALLOWED_BARE = -5,
1235-
};
1236-
12371224
/*
12381225
* We cannot decide in this function whether we are in the work tree or
12391226
* not, since the config can only be read _after_ this function was called.
@@ -1385,21 +1372,23 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
13851372
}
13861373
}
13871374

1388-
int discover_git_directory(struct strbuf *commondir,
1389-
struct strbuf *gitdir)
1375+
enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
1376+
struct strbuf *gitdir)
13901377
{
13911378
struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
13921379
size_t gitdir_offset = gitdir->len, cwd_len;
13931380
size_t commondir_offset = commondir->len;
13941381
struct repository_format candidate = REPOSITORY_FORMAT_INIT;
1382+
enum discovery_result result;
13951383

13961384
if (strbuf_getcwd(&dir))
1397-
return -1;
1385+
return GIT_DIR_CWD_FAILURE;
13981386

13991387
cwd_len = dir.len;
1400-
if (setup_git_directory_gently_1(&dir, gitdir, NULL, 0) <= 0) {
1388+
result = setup_git_directory_gently_1(&dir, gitdir, NULL, 0);
1389+
if (result <= 0) {
14011390
strbuf_release(&dir);
1402-
return -1;
1391+
return result;
14031392
}
14041393

14051394
/*
@@ -1429,11 +1418,11 @@ int discover_git_directory(struct strbuf *commondir,
14291418
strbuf_setlen(commondir, commondir_offset);
14301419
strbuf_setlen(gitdir, gitdir_offset);
14311420
clear_repository_format(&candidate);
1432-
return -1;
1421+
return GIT_DIR_INVALID_FORMAT;
14331422
}
14341423

14351424
clear_repository_format(&candidate);
1436-
return 0;
1425+
return result;
14371426
}
14381427

14391428
const char *setup_git_directory_gently(int *nongit_ok)
@@ -1515,10 +1504,11 @@ const char *setup_git_directory_gently(int *nongit_ok)
15151504
}
15161505
*nongit_ok = 1;
15171506
break;
1518-
case GIT_DIR_NONE:
1507+
case GIT_DIR_CWD_FAILURE:
1508+
case GIT_DIR_INVALID_FORMAT:
15191509
/*
15201510
* As a safeguard against setup_git_directory_gently_1 returning
1521-
* this value, fallthrough to BUG. Otherwise it is possible to
1511+
* these values, fallthrough to BUG. Otherwise it is possible to
15221512
* set startup_info->have_repository to 1 when we did nothing to
15231513
* find a repository.
15241514
*/

setup.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,45 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code);
4242
#define resolve_gitdir(path) resolve_gitdir_gently((path), NULL)
4343

4444
void setup_work_tree(void);
45+
46+
/*
47+
* discover_git_directory_reason() is similar to discover_git_directory(),
48+
* except it returns an enum value instead. It is important to note that
49+
* a zero-valued return here is actually GIT_DIR_NONE, which is different
50+
* from discover_git_directory.
51+
*/
52+
enum discovery_result {
53+
GIT_DIR_EXPLICIT = 1,
54+
GIT_DIR_DISCOVERED = 2,
55+
GIT_DIR_BARE = 3,
56+
/* these are errors */
57+
GIT_DIR_HIT_CEILING = -1,
58+
GIT_DIR_HIT_MOUNT_POINT = -2,
59+
GIT_DIR_INVALID_GITFILE = -3,
60+
GIT_DIR_INVALID_OWNERSHIP = -4,
61+
GIT_DIR_DISALLOWED_BARE = -5,
62+
GIT_DIR_INVALID_FORMAT = -6,
63+
GIT_DIR_CWD_FAILURE = -7,
64+
};
65+
enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
66+
struct strbuf *gitdir);
67+
4568
/*
4669
* Find the commondir and gitdir of the repository that contains the current
4770
* working directory, without changing the working directory or other global
4871
* state. The result is appended to commondir and gitdir. If the discovered
4972
* gitdir does not correspond to a worktree, then 'commondir' and 'gitdir' will
5073
* both have the same result appended to the buffer. The return value is
51-
* either 0 upon success and non-zero if no repository was found.
74+
* either 0 upon success and -1 if no repository was found.
5275
*/
53-
int discover_git_directory(struct strbuf *commondir,
54-
struct strbuf *gitdir);
76+
static inline int discover_git_directory(struct strbuf *commondir,
77+
struct strbuf *gitdir)
78+
{
79+
if (discover_git_directory_reason(commondir, gitdir) <= 0)
80+
return -1;
81+
return 0;
82+
}
83+
5584
const char *setup_git_directory_gently(int *);
5685
const char *setup_git_directory(void);
5786
char *prefix_path(const char *prefix, int len, const char *path);

t/t9211-scalar-clone.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,16 @@ test_expect_success 'scalar clone warns when background maintenance fails' '
180180
grep "could not turn on maintenance" err
181181
'
182182

183+
test_expect_success '`scalar clone --no-src`' '
184+
scalar clone --src "file://$(pwd)/to-clone" with-src &&
185+
scalar clone --no-src "file://$(pwd)/to-clone" without-src &&
186+
187+
test_path_is_dir with-src/src &&
188+
test_path_is_missing without-src/src &&
189+
190+
(cd with-src/src && ls ?*) >with &&
191+
(cd without-src && ls ?*) >without &&
192+
test_cmp with without
193+
'
194+
183195
test_done

0 commit comments

Comments
 (0)