Skip to content

git son: add command to create independent child repositories#2122

Open
Evandabest wants to merge 5 commits into
gitgitgadget:masterfrom
Evandabest:git-son
Open

git son: add command to create independent child repositories#2122
Evandabest wants to merge 5 commits into
gitgitgadget:masterfrom
Evandabest:git-son

Conversation

@Evandabest
Copy link
Copy Markdown

@Evandabest Evandabest commented May 22, 2026

Motivation

When spinning off a new project that is related to an existing repository, there is no built-in way to create a child repository that maintains a link back to its parent without the tight coupling of submodules. Submodules pin the child to a specific commit and require the parent to track the child in its index, which is too heavyweight when the child is meant to be fully independent.

The typical workflow today is manual: git init, git remote add, update .gitignore — three steps that are easy to forget or get wrong. git son automates this and establishes a lightweight convention for the parent-child relationship: a remote named parent in the child, and nothing in the parent except an ignore rule.

Summary

This series introduces git son, a new porcelain command that creates an independent child repository inside the current working tree. Unlike a submodule, the child is not tracked by the parent; instead, its subdirectory is added to the parent's .gitignore. The child is configured at creation time with a remote named parent pointing back to the parent repository's origin URL (or local path if no origin exists), making the lineage explicit and recoverable via standard Git commands.

Changes

  • git-son.sh: new shell script implementing the command, supporting --inherit to fetch parent history at creation time and --branch <branch> (requires --inherit) to check out a specific parent branch
  • git-son registered in command-list.txt as mainporcelain
  • git-son.sh added to SCRIPT_SH in Makefile and to scripts_sh in meson.build
  • Documentation/git-son.adoc: new man page covering synopsis, option descriptions, and worked examples
  • Documentation/meson.build: git-son.adoc added to the manpage build list
  • t/t5151-son.sh: new test script covering basic creation, parent remote configuration, .gitignore update, idempotency failure, flag validation, and
    --inherit with a bare remote

Details

The key design property is independence: the child is a fully self-contained repository with no entry in the parent's index. The parent remote is the only artifact linking the two, which means git fetch parent and git log parent/<branch> work as expected from within the child without any special tooling.

The --branch flag is intentionally restricted to --inherit mode. Without fetching, there is no remote-tracking branch to check out from, so accepting --branch alone would be misleading; the command dies with a clear diagnostic in that case.

When no origin URL is available in the parent, the parent remote is set to the parent's absolute local path. This covers the common case of repositories that have never been pushed to a remote.

Testing

t/t5151-son.sh covers the following scenarios:

  • Basic child repository creation (directory exists, .git present)
  • parent remote is correctly recorded in the child
  • Child directory is appended to the parent's .gitignore
  • Child starts with exactly one initial commit when --inherit is not used
  • Command fails without leaving a directory when the target already exists
  • --branch without --inherit is rejected before any filesystem changes
  • --inherit fetches parent history and the remote-tracking branch is reachable in the child

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

Welcome to GitGitGadget

Hi @Evandabest, and welcome to GitGitGadget, the GitHub App to send patch series to the Git mailing list from GitHub Pull Requests.

Please make sure that either:

  • Your Pull Request has a good description, if it consists of multiple commits, as it will be used as cover letter.
  • Your Pull Request description is empty, if it consists of a single commit, as the commit message should be descriptive enough by itself.

You can CC potential reviewers by adding a footer to the PR description with the following syntax:

CC: Revi Ewer <revi.ewer@example.com>, Ill Takalook <ill.takalook@example.net>

NOTE: DO NOT copy/paste your CC list from a previous GGG PR's description,
because it will result in a malformed CC list on the mailing list. See
example.

Also, it is a good idea to review the commit messages one last time, as the Git project expects them in a quite specific form:

  • the lines should not exceed 76 columns,
  • the first line should be like a header and typically start with a prefix like "tests:" or "revisions:" to state which subsystem the change is about, and
  • the commit messages' body should be describing the "why?" of the change.
  • Finally, the commit messages should end in a Signed-off-by: line matching the commits' author.

It is in general a good idea to await the automated test ("Checks") in this Pull Request before contributing the patches, e.g. to avoid trivial issues such as unportable code.

Contributing the patches

Before you can contribute the patches, your GitHub username needs to be added to the list of permitted users. Any already-permitted user can do that, by adding a comment to your PR of the form /allow. A good way to find other contributors is to locate recent pull requests where someone has been /allowed:

Both the person who commented /allow and the PR author are able to /allow you.

An alternative is the channel #git-devel on the Libera Chat IRC network:

<newcontributor> I've just created my first PR, could someone please /allow me? https://github.com/gitgitgadget/git/pull/12345
<veteran> newcontributor: it is done
<newcontributor> thanks!

Once on the list of permitted usernames, you can contribute the patches to the Git mailing list by adding a PR comment /submit.

If you want to see what email(s) would be sent for a /submit request, add a PR comment /preview to have the email(s) sent to you. You must have a public GitHub email address for this. Note that any reviewers CC'd via the list in the PR description will not actually be sent emails.

After you submit, GitGitGadget will respond with another comment that contains the link to the cover letter mail in the Git mailing list archive. Please make sure to monitor the discussion in that thread and to address comments and suggestions (while the comments and suggestions will be mirrored into the PR by GitGitGadget, you will still want to reply via mail).

If you do not want to subscribe to the Git mailing list just to be able to respond to a mail, you can download the mbox from the Git mailing list archive (click the (raw) link), then import it into your mail program. If you use GMail, you can do this via:

curl -g --user "<EMailAddress>:<Password>" \
    --url "imaps://imap.gmail.com/INBOX" -T /path/to/raw.txt

To iterate on your change, i.e. send a revised patch or patch series, you will first want to (force-)push to the same branch. You probably also want to modify your Pull Request description (or title). It is a good idea to summarize the revision by adding something like this to the cover letter (read: by editing the first comment on the PR, i.e. the PR description):

Changes since v1:
- Fixed a typo in the commit message (found by ...)
- Added a code comment to ... as suggested by ...
...

To send a new iteration, just add another PR comment with the contents: /submit.

Need help?

New contributors who want advice are encouraged to join git-mentoring@googlegroups.com, where volunteers who regularly contribute to Git are willing to answer newbie questions, give advice, or otherwise provide mentoring to interested contributors. You must join in order to post or view messages, but anyone can join.

You may also be able to find help in real time in the developer IRC channel, #git-devel on Libera Chat. Remember that IRC does not support offline messaging, so if you send someone a private message and log out, they cannot respond to you. The scrollback of #git-devel is archived, though.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit b627ec5:
Add git-son: create independent child repositories

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 1b98825:
git-son: register in Makefile and meson build system

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 21680fc:
git-son: add to command list as mainporcelain

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 52c738e:
git-son: add documentation

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 4bb623d:
git-son: add tests

  • Commit checks stopped - the message is too short
  • Commit not signed off

@Evandabest Evandabest force-pushed the git-son branch 3 times, most recently from 5decf27 to 26d7fe0 Compare May 22, 2026 23:49
@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 0326cf4:
``

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 4ba29cb:
``

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 46fba44:
``

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

There are issues in commit 26d7fe0:
``

  • Commit checks stopped - the message is too short
  • Commit not signed off

Introduce git-son, a new porcelain command that creates an independent
child repository inside the current working tree. Unlike submodules,
the child is not tracked by the parent; instead its directory is added
to the parent's .gitignore and a "parent" remote is configured in the
child pointing back to the parent's origin URL or local path.

This gives users a lightweight way to spin off a related repository
that knows where it came from without the coupling that submodules
impose.

The command supports two optional flags:

  --inherit    fetch the parent's history into the child at creation
  --branch     check out a specific parent branch (requires --inherit)

Assisted-by: Claude Opus 4.6
Signed-off-by: Evan Haque <evanhaque1@gmail.com>
Add git-son.sh to SCRIPT_SH in the Makefile and to the scripts_sh
array in meson.build so that the script is installed alongside the
other shell-based Git commands during "make install" and meson builds.

Also add /git-son to .gitignore so that the build artifact produced
from git-son.sh is not flagged as an untracked file.

Assisted-by: Claude Opus 4.6
Signed-off-by: Evan Haque <evanhaque1@gmail.com>
Register git-son in command-list.txt as a mainporcelain command so
that it appears in "git help" output and is discoverable through the
standard help machinery.

Assisted-by: Claude Opus 4.6
Signed-off-by: Evan Haque <evanhaque1@gmail.com>
Add a man page (git-son.adoc) documenting the synopsis, options, and
usage examples for the new command. Register the page in
Documentation/meson.build so it is built by the meson doc target.

Assisted-by: Claude Opus 4.6
Signed-off-by: Evan Haque <evanhaque1@gmail.com>
Add t5151-son.sh with nine test cases covering:

 - basic child repository creation
 - parent remote configuration in the child
 - .gitignore update in the parent
 - initial commit presence in the child
 - failure when the target directory already exists
 - --branch without --inherit is rejected cleanly
 - no leftover directory on validation failure
 - --inherit fetches parent history

Register the test in t/meson.build so the meson build system
discovers and runs it.

Assisted-by: Claude Opus 4.6
Signed-off-by: Evan Haque <evanhaque1@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant