This issue is related to:
Repo auto-initialization not always welcome and/or useful
As currently implemented, the ads-github-repo-create tool unconditionally initializes the newly created repository (it always passes the auto_init parameter to the repo creation API endpoint). As noted in the source code comments, that is done in order to support the use case of the user explicitly requesting a default branch named something other than the default, but is not otherwise necessary for creating the repo. We should not insist on this behavior for all newly created repos. Not only is the behavior not always needed, it also gets in the way sometimes.
Rationale for current behavior: consistency & ease of use
The rationale for the existing behavior is that the tool always behaves the same way: the user always ends up with a repository created to spec and (for better or for worse) has already been initialized (with a minimal 'README.md' file). The original motivation was to make the behavior consistent to minimize the need for the user to understand and navigate intricacies of the tool that would make it more difficult to use. While that might sound reasonable, in practice the behavior has already shown itself to be a hindrance, as discussed below.
Unwanted consequences of repo auto-intialization
Beyond repo initialization not always being necessary, even if the user wishes to use a default branch name other than the default, it is not strictly necessary that the user have the ads-github-repo-create tool perform the work to make it so. For example, when a user creates and then clones an empty repo (one that does not yet have any commits), the local git configuration on the user's machine will determine the name of the default branch (which will honor the user's (or system's) init.defaultBranch configuration item for git >= 2.28).
If the user has created the empty repo with the intention of adding new code from scratch, then the current behavior does not matter too much one way or the other. When the user clones the repo, the default branch will be what was specified and the repo (because it was auto-initialized) will have a minimal README.md file as its only existing content. Since this is the starting point for development, there is no existing repository metadata to be concerned about; the user is free to start adding files and otherwise committing and pushing changes on the default branch.
OTOH, if the user has created the empty repo with the intention of pushing content from an existing git repository, then the current approach of the ads-github-repo-create always auto-initializing the GitHub repo actually gets in the user's way. Let's say the existing repo was converted from a Subversion repository at some time in the past, and (for historical reasons) uses trunk as the default branch name. The user would be performing the following steps to get that repo into GitHub:
$ ads-github-repo-create -v -b 'trunk' -d 'my repo blurb' -- my-repo-name
ads-github-repo-create (info): GitHub repo owner is: whoever
ads-github-repo-create (info): GitHub repository does not yet exist: whoever/my-repo-name
ads-github-repo-create (info): attempting to create new GitHup repo: whoever/my-repo-name
ads-github-repo-create (info): successfully created new GitHup repo: whoever/my-repo-name
ads-github-repo-create (info): specific default branch name specified; doing clone/rename dance
ads-github-repo-create (info): [local repo] clone newly created repo....done.
ads-github-repo-create (info): [local repo] on default branch; renaming it....done.
ads-github-repo-create (info): [local repo] pushing renamed branch to origin....done.
ads-github-repo-create (info): [local repo] track new branch from upstream....done.
ads-github-repo-create (info): [local repo] pointing HEAD to trunk....done.
ads-github-repo-create (info): remotely: attempting to PATCH dflt branch name for GitHup repo: whoever/my-repo-name
ads-github-repo-create (info): successfully PATCHed existing GitHup repo: whoever/my-repo-name
ads-github-repo-create (info): successfully changed default branch for existing GitHup repo: whoever/my-repo-name
ads-github-repo-create (info): [remote repo] delete old default branch from GitHub repo....done.
ads-github-repo-create (info): successfully changed default branch for GitHup repo: whoever/my-repo-name
Summary of newly created repository:
Name: my-repo-name
Is fork?: no
Owner: whoever
Is archived?: no
Is disabled?: no
Created at: 2020-10-10 19:20:13+0000
Updated at: 2020-10-10 19:20:18+0000
Is private?: no
Visibility: -
Default branch: trunk
Has issues?: yes
Has projects?: yes
Has wiki?: yes
GitHub: https://github.com/whoever/my-repo-name
Homepage: -
Description: my repo blurb
Clone via ssh: git@github.com:whoever/my-repo-name.git
Clone via https: https://github.com/whoever/my-repo-name.git
$ cd /path/to/existing/repo/working/dir/for/my-repo-name
$ git remote add origin 'git@github.com:whoever/my-repo-name.git'
$ git remote update origin
Fetching origin
From github.com:whoever/my-repo-name
* [new branch] trunk -> origin/trunk
$ git push --set-upstream --follow-tags origin trunk
To github.com:whoever/my-repo-name.git
! [rejected] trunk -> trunk (non-fast-forward)
error: failed to push some refs to 'github.com:whoever/my-repo-name.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Sure there are ways to work through that situation (mainly by way of doing a force push), but that is a lousy user experience, and could be a major hindrance to folks not already comfortable using git.
New approach
A more flexible approach might be to:
-
Introduce a new -a (--auto-init) command line option to allow the user to explicitly request auto-initialization (regardless of whether or not the user has requested a specific default branch name).
-
Document that the existing -d (--default-branch=NAME) option implies the new -a (--auto-init) option, as well.
This would allow for the creation of the GitHub repo with or without auto-initialization at the user's request, similar to the user making the same decision in the GitHub web UI when creating a new repo.
A user starting work on a brand new repo would likely request the repo auto-initialization:
$ ads-github-repo-create -v -a -b 'whatever' -d 'Mumble mumble' -- some-repo
...
$ git clone 'git@github.com:whoever/some-repo.git'
...
$ cd some-repo
$ ls
README.md
The repo auto-initialization would not be forced upon the user attempting to get that old Subversion-to-git repo into GitHub.
Option '-a' (--auto-init) does not necessarily mean the "auto_init" parameter
It would work to use the GitHub v3 API's auto_init parameter when creating the repository to cause a minimal README.md to be committed to the new repo; in fact, this is how the tool works currently.
For the purpose of establishing a default branch name that is different from the default, it may require fewer dance maneuvers to clone an empty repo with a specific branch named for the working directory, and then make the initial commit against that branch. If that works as expected, then that would save the additional steps currently used because it would eliminate the branch renaming and HEAD re-pointing on both ends.
We might want to support both approaches, though, in order to avoid interfering with the use of GitHub template repos (which are not currently supported by ads-github-tools).
UPDATE (2020-10-11 14:18): Supporting repo auto-intialization with feature-for-feature parity with the GitHub UI would require supporting separate knobs for conditionally generating a README.md file, a .gitignore file, and selection of of a license file. Of those three, I've personally found only the README.md file to be useful (and only marginally so). Furthermore, the intent of providing those knobs would be better served by using GitHub template repos. For now, at least, there is no need to support them individually.
When ads-github-repo-create needs to auto-initialize a repository, it can do so in a local, empty clone of the newly created GitHub repo. If we decide to do it that way, auto-initialization would entail the generation of a minimal README.md file and committing it. Producing content that matches what GitHub currently generates for this purpose is simple: If a repo description is not provided, then the file contents are just this without a trailing newline:
<quote>
# ${REPO_NAME}</quote>
If a repo description is provided, then the file contents look like this (including the trailing newline on the second line):
<quote>
# ${REPO_NAME}
${REPO_DESC}
</quote>
For the purposes of the ads-github-tools, we would ensure that the file always ends with a newline either way.
Manual repo initialization vs. "auto_init" param
The main benefit of using the auto_init parameter of the GitHub v3 API during repo creation is that the initialization is done by the GitHub API itself -- whatever that means. If that behavior changes over time, then we would get the new behaviors "for free". This might be the easiest way to remain consistent with how the GitHub web UI behaves, if that were desirable.
The main downsides to using the auto_init parameter are:
-
Exact consistency with the GitHub web UI is not actually desirable.
-
If the user requested a specific default branch name, then in order to carry out that request the ads-github-repo-create program needs to jump through more hoops in order to achieve that end state. The program currently does that particular dance, but it can be simplified (which should also make it more robust) if it just performs most of the branch renaming work locally rather than having to hop back and forth to delete unwanted artifacts auto-created in the repo repo due to the auto_init param.
Since repo initialization is so simple (basically just entailing the creation of the README.md file and committing it), we should lean in the direction of just doing it locally. That way we can simplify our branch renaming logic, as well.
Potential downside to the new approach
The new approach will require that the user be cognizant of whether auto-initialization will be helpful to or an annoyance for the task at hand. We're not worried about that being much of a problem, though, because that will be preferable to the current behavior in which the tool gets in the way for some common tasks.
This issue is related to:
Repo auto-initialization not always welcome and/or useful
As currently implemented, the
ads-github-repo-createtool unconditionally initializes the newly created repository (it always passes theauto_initparameter to the repo creation API endpoint). As noted in the source code comments, that is done in order to support the use case of the user explicitly requesting a default branch named something other than the default, but is not otherwise necessary for creating the repo. We should not insist on this behavior for all newly created repos. Not only is the behavior not always needed, it also gets in the way sometimes.Rationale for current behavior: consistency & ease of use
The rationale for the existing behavior is that the tool always behaves the same way: the user always ends up with a repository created to spec and (for better or for worse) has already been initialized (with a minimal 'README.md' file). The original motivation was to make the behavior consistent to minimize the need for the user to understand and navigate intricacies of the tool that would make it more difficult to use. While that might sound reasonable, in practice the behavior has already shown itself to be a hindrance, as discussed below.
Unwanted consequences of repo auto-intialization
Beyond repo initialization not always being necessary, even if the user wishes to use a default branch name other than the default, it is not strictly necessary that the user have the
ads-github-repo-createtool perform the work to make it so. For example, when a user creates and then clones an empty repo (one that does not yet have any commits), the localgitconfiguration on the user's machine will determine the name of the default branch (which will honor the user's (or system's)init.defaultBranchconfiguration item for git >= 2.28).If the user has created the empty repo with the intention of adding new code from scratch, then the current behavior does not matter too much one way or the other. When the user clones the repo, the default branch will be what was specified and the repo (because it was auto-initialized) will have a minimal
README.mdfile as its only existing content. Since this is the starting point for development, there is no existing repository metadata to be concerned about; the user is free to start adding files and otherwise committing and pushing changes on the default branch.OTOH, if the user has created the empty repo with the intention of pushing content from an existing
gitrepository, then the current approach of theads-github-repo-createalways auto-initializing the GitHub repo actually gets in the user's way. Let's say the existing repo was converted from a Subversion repository at some time in the past, and (for historical reasons) usestrunkas the default branch name. The user would be performing the following steps to get that repo into GitHub:$ ads-github-repo-create -v -b 'trunk' -d 'my repo blurb' -- my-repo-name ads-github-repo-create (info): GitHub repo owner is: whoever ads-github-repo-create (info): GitHub repository does not yet exist: whoever/my-repo-name ads-github-repo-create (info): attempting to create new GitHup repo: whoever/my-repo-name ads-github-repo-create (info): successfully created new GitHup repo: whoever/my-repo-name ads-github-repo-create (info): specific default branch name specified; doing clone/rename dance ads-github-repo-create (info): [local repo] clone newly created repo....done. ads-github-repo-create (info): [local repo] on default branch; renaming it....done. ads-github-repo-create (info): [local repo] pushing renamed branch to origin....done. ads-github-repo-create (info): [local repo] track new branch from upstream....done. ads-github-repo-create (info): [local repo] pointing HEAD to trunk....done. ads-github-repo-create (info): remotely: attempting to PATCH dflt branch name for GitHup repo: whoever/my-repo-name ads-github-repo-create (info): successfully PATCHed existing GitHup repo: whoever/my-repo-name ads-github-repo-create (info): successfully changed default branch for existing GitHup repo: whoever/my-repo-name ads-github-repo-create (info): [remote repo] delete old default branch from GitHub repo....done. ads-github-repo-create (info): successfully changed default branch for GitHup repo: whoever/my-repo-name Summary of newly created repository: Name: my-repo-name Is fork?: no Owner: whoever Is archived?: no Is disabled?: no Created at: 2020-10-10 19:20:13+0000 Updated at: 2020-10-10 19:20:18+0000 Is private?: no Visibility: - Default branch: trunk Has issues?: yes Has projects?: yes Has wiki?: yes GitHub: https://github.com/whoever/my-repo-name Homepage: - Description: my repo blurb Clone via ssh: git@github.com:whoever/my-repo-name.git Clone via https: https://github.com/whoever/my-repo-name.git $ cd /path/to/existing/repo/working/dir/for/my-repo-name $ git remote add origin 'git@github.com:whoever/my-repo-name.git' $ git remote update origin Fetching origin From github.com:whoever/my-repo-name * [new branch] trunk -> origin/trunk $ git push --set-upstream --follow-tags origin trunk To github.com:whoever/my-repo-name.git ! [rejected] trunk -> trunk (non-fast-forward) error: failed to push some refs to 'github.com:whoever/my-repo-name.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.Sure there are ways to work through that situation (mainly by way of doing a force push), but that is a lousy user experience, and could be a major hindrance to folks not already comfortable using git.
New approach
A more flexible approach might be to:
Introduce a new
-a(--auto-init) command line option to allow the user to explicitly request auto-initialization (regardless of whether or not the user has requested a specific default branch name).Document that the existing
-d(--default-branch=NAME) option implies the new-a(--auto-init) option, as well.This would allow for the creation of the GitHub repo with or without auto-initialization at the user's request, similar to the user making the same decision in the GitHub web UI when creating a new repo.
A user starting work on a brand new repo would likely request the repo auto-initialization:
$ ads-github-repo-create -v -a -b 'whatever' -d 'Mumble mumble' -- some-repo ... $ git clone 'git@github.com:whoever/some-repo.git' ... $ cd some-repo $ ls README.mdThe repo auto-initialization would not be forced upon the user attempting to get that old Subversion-to-git repo into GitHub.
Option '-a' (--auto-init) does not necessarily mean the "auto_init" parameter
It would work to use the GitHub v3 API's
auto_initparameter when creating the repository to cause a minimalREADME.mdto be committed to the new repo; in fact, this is how the tool works currently.For the purpose of establishing a default branch name that is different from the default, it may require fewer dance maneuvers to clone an empty repo with a specific branch named for the working directory, and then make the initial commit against that branch. If that works as expected, then that would save the additional steps currently used because it would eliminate the branch renaming and
HEADre-pointing on both ends.We might want to support both approaches, though, in order to avoid interfering with the use of GitHub template repos (which are not currently supported by
ads-github-tools).UPDATE (2020-10-11 14:18): Supporting repo auto-intialization with feature-for-feature parity with the GitHub UI would require supporting separate knobs for conditionally generating a
README.mdfile, a.gitignorefile, and selection of of a license file. Of those three, I've personally found only theREADME.mdfile to be useful (and only marginally so). Furthermore, the intent of providing those knobs would be better served by using GitHub template repos. For now, at least, there is no need to support them individually.When
ads-github-repo-createneeds to auto-initialize a repository, it can do so in a local, empty clone of the newly created GitHub repo. If we decide to do it that way, auto-initialization would entail the generation of a minimalREADME.mdfile and committing it. Producing content that matches what GitHub currently generates for this purpose is simple: If a repo description is not provided, then the file contents are just this without a trailing newline:If a repo description is provided, then the file contents look like this (including the trailing newline on the second line):
For the purposes of the
ads-github-tools, we would ensure that the file always ends with a newline either way.Manual repo initialization vs. "auto_init" param
The main benefit of using the
auto_initparameter of the GitHub v3 API during repo creation is that the initialization is done by the GitHub API itself -- whatever that means. If that behavior changes over time, then we would get the new behaviors "for free". This might be the easiest way to remain consistent with how the GitHub web UI behaves, if that were desirable.The main downsides to using the
auto_initparameter are:Exact consistency with the GitHub web UI is not actually desirable.
If the user requested a specific default branch name, then in order to carry out that request the
ads-github-repo-createprogram needs to jump through more hoops in order to achieve that end state. The program currently does that particular dance, but it can be simplified (which should also make it more robust) if it just performs most of the branch renaming work locally rather than having to hop back and forth to delete unwanted artifacts auto-created in the repo repo due to theauto_initparam.Since repo initialization is so simple (basically just entailing the creation of the
README.mdfile and committing it), we should lean in the direction of just doing it locally. That way we can simplify our branch renaming logic, as well.Potential downside to the new approach
The new approach will require that the user be cognizant of whether auto-initialization will be helpful to or an annoyance for the task at hand. We're not worried about that being much of a problem, though, because that will be preferable to the current behavior in which the tool gets in the way for some common tasks.