From: Mark Jamsek Subject: got: gotadmin init and got import -b coherence To: Game of Trees Date: Sun, 21 Aug 2022 00:01:33 +1000 I introduced some Fossilers to Got today and came across this issue. In Fossil, the default branch is "trunk", so for familiarity I thought I'd use the -b option to `got import` to make the initial commit on "trunk" and thus expected HEAD to reference "trunk": $ gotadmin init new.git $ got import -r new.git -b trunk -m "initial commit" ~/src/tmp A /home/mark/src/tmp/runnit.c Created branch refs/heads/trunk with commit 85e40007698d1e988e97d8c8f94171f77b2a8579 $ got co new.git got: reference refs/heads/main not found $ got co -b trunk new.git A /home/mark/src/new/runnit.c Checked out refs/heads/trunk: 85e40007698d1e988e97d8c8f94171f77b2a8579 Now shut up and hack $ cd new && tog tog: reference refs/heads/main not found $ got log got: reference refs/heads/main not found $ got log -c trunk got: reference refs/heads/main not found As a new repository, I incorrectly assumed that `got import -b trunk` would make HEAD point to "trunk". However, HEAD is still "main", which doesn't exist. I just had a quick look and made this patch to check if we create new repositories with a "trunk" HEAD if anything noticeable breaks. $ gotadmin init -b trunk new.git $ got import -r new.git -b trunk -m "initial commit" ~/src/tmp A /home/mark/src/tmp/runnit.c Created branch refs/heads/trunk with commit bafecf8a578c2a1d80dcfdc81084840453d30007 $ got co new.git A /home/mark/src/new/runnit.c Checked out refs/heads/trunk: bafecf8a578c2a1d80dcfdc81084840453d30007 Now shut up and hack $ cd new && got log ----------------------------------------------- commit bafecf8a578c2a1d80dcfdc81084840453d30007 (trunk) from: Mark Jamsek date: Sat Aug 20 13:47:28 2022 UTC initial commit So far so good, but I have a few questions: - have I missed something and there's already a way to do this? - assuming I haven't, do we just want users to manually edit repo.git/HEAD if they want a new repo with something other than "main"? - if not, are we open to something like this (or something else entirely) so users can make HEAD reference when creating new repositories? - if yes, I'm not sure I like making the user have to use -b with `gotadmin init` and then again with `got import`; would it be better to either read or write HEAD during import so the user only needs to use -b once (either with `gotadmin init -b` or `got import -b`) to have HEAD point to something other than "main"? OTOH, it's at least consistent and easy to remember using -b for both init and import, and the change is minimal diff refs/heads/main refs/heads/dev/gotadmin commit - 026ac2c462910064c5c9143a96b17a920e6bbc58 commit + 8bb9f49eecff4b8726dd1c5106c73be2d2c6f809 blob - d629445e1b234fb60ebb1aa76195a8d2283e029a blob + 9ac4cf70ccec9e2b1921968caa1c627d5d682d86 --- got/got.1 +++ got/got.1 @@ -102,7 +102,12 @@ instead of creating the default branch .Dq main . Use of this option is required if the .Dq main -branch already exists. +branch already exists, or if the +.Fl b +option was used to specify a branch other than +.Dq main +as the repository's HEAD reference when creating the repository with +.Cm gotadmin init . .It Fl I Ar pattern Ignore files or directories with a name which matches the specified .Ar pattern . blob - f9bcb1bca8436bc052e3bdeab3be53a13add0a61 blob + ee8fd1138f21031552a0957b443e5c0c66b2eb9f --- got/got.c +++ got/got.c @@ -1689,7 +1689,7 @@ cmd_clone(int argc, char *argv[]) goto done; if (!list_refs_only) { - error = got_repo_init(repo_path); + error = got_repo_init(repo_path, NULL); if (error) goto done; error = got_repo_pack_fds_open(&pack_fds); blob - 0f970bf8e42b6329fb4b1718ff50f3d637eb442f blob + 521816ab92f9c7d69e823c06dd5b547a1381eeb9 --- gotadmin/gotadmin.1 +++ gotadmin/gotadmin.1 @@ -53,7 +53,7 @@ The commands for .Nm are as follows: .Bl -tag -width checkout -.It Cm init Ar repository-path +.It Cm init Oo Fl b Ar branch Oc Ar repository-path Create a new empty repository at the specified .Ar repository-path . .Pp @@ -64,6 +64,17 @@ the command must be used to populate the empty repository before .Cm got checkout can be used. +.Pp +The options for +.Cm gotadmin init +are as follows: +.Bl -tag -width Ds +.It Fl b Ar branch +Make the specified +.Ar branch +resolve to the repository's HEAD reference instead of the default branch +.Dq main . +.El .It Cm info Oo Fl r Ar repository-path Oc Display information about a repository. This includes some configuration settings from blob - cc47823cd2100f2565e4172a84472e2fb5ffd7bd blob + 3d80a49a286807837e83114ca3528a1bf989113d --- gotadmin/gotadmin.c +++ gotadmin/gotadmin.c @@ -279,11 +279,15 @@ static const struct got_error * cmd_init(int argc, char *argv[]) { const struct got_error *error = NULL; + const char *head_name = NULL; char *repo_path = NULL; int ch; - while ((ch = getopt(argc, argv, "")) != -1) { + while ((ch = getopt(argc, argv, "b:")) != -1) { switch (ch) { + case 'b': + head_name = optarg; + break; default: usage_init(); /* NOTREACHED */ @@ -315,7 +319,7 @@ cmd_init(int argc, char *argv[]) if (error) goto done; - error = got_repo_init(repo_path); + error = got_repo_init(repo_path, head_name); done: free(repo_path); return error; blob - dea6dd81d267dfa92571a33f5c7559726bab8d8b blob + 4f8b24e0e19f1af4e21707388cf9bbf9bb54cd18 --- include/got_repository.h +++ include/got_repository.h @@ -130,8 +130,11 @@ int got_repo_is_bare(struct got_repository *); const struct got_error *got_repo_map_path(char **, struct got_repository *, const char *); -/* Create a new repository in an empty directory at a specified path. */ -const struct got_error *got_repo_init(const char *); +/* + * Create a new repository with optional specified + * HEAD ref in an empty directory at a specified path. + */ +const struct got_error *got_repo_init(const char *, const char *); /* Attempt to find a unique object ID for a given ID string prefix. */ const struct got_error *got_repo_match_object_id_prefix(struct got_object_id **, blob - a47b26a8fcc75a0889cc09cd5b7230842ec0ae6e blob + ca38bdf3f2d2c88d5eadccd7572dc438ee6b667a --- lib/repository.c +++ lib/repository.c @@ -1552,7 +1552,7 @@ got_repo_unpin_pack(struct got_repository *repo) } const struct got_error * -got_repo_init(const char *repo_path) +got_repo_init(const char *repo_path, const char *head_name) { const struct got_error *err = NULL; const char *dirnames[] = { @@ -1562,12 +1562,12 @@ got_repo_init(const char *repo_path) }; const char *description_str = "Unnamed repository; " "edit this file 'description' to name the repository."; - const char *headref_str = "ref: refs/heads/main"; + const char *headref = "ref: refs/heads/"; const char *gitconfig_str = "[core]\n" "\trepositoryformatversion = 0\n" "\tfilemode = true\n" "\tbare = true\n"; - char *path; + char *headref_str, *path; size_t i; if (!got_path_dir_is_empty(repo_path)) @@ -1592,7 +1592,13 @@ got_repo_init(const char *repo_path) if (asprintf(&path, "%s/%s", repo_path, GOT_HEAD_FILE) == -1) return got_error_from_errno("asprintf"); + if (asprintf(&headref_str, "%s%s", headref, + head_name ? head_name : "main") == -1) { + free(path); + return got_error_from_errno("asprintf"); + } err = got_path_create_file(path, headref_str); + free(headref_str); free(path); if (err) return err; -- Mark Jamsek GPG: F2FF 13DE 6A06 C471 CA80 E6E2 2930 DC66 86EE CF68