From f20c649008013d8f152dd5b2038e6c9dc2450428 Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 20:59:19 +0000 Subject: [PATCH 1/8] Adding git-adopt to bin/ --- bin/git-adopt | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 bin/git-adopt diff --git a/bin/git-adopt b/bin/git-adopt new file mode 100755 index 00000000..853465c5 --- /dev/null +++ b/bin/git-adopt @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# +# (The MIT License) +# +# Copyright (c) 2025 Neal Fultz +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# 'Software'), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# The below is a small script for dotfile management. + +adopt () { + + if [ "$1" == "-d" ]; then + local DEBUG + DEBUG=echo + shift + fi + + local package + package="$1" + shift + + local has_git + local repo + local target + + if hash git 2>/dev/null ; then + has_git=1 + repo=$(git config --path --default "$HOME/.dotfiles" adopt.repo) + target=$(git config --path --default "$HOME" adopt.target) + else + has_git=0 + repo=${repo:-$HOME/.dotfiles} + target=${target:-$HOME} + fi + + + + + package="$package${PWD#*$target}" + $DEBUG mkdir -p "$repo/$package" + + for i in "$@" + do + dn=$(dirname $i) + [ -n "$dn" ] && $DEBUG mkdir -p $repo/$package/$dn + $DEBUG mv $i $repo/$package/$dn + $DEBUG ln -rs $repo/$package/$i $i + if [ $has_git -gt 0 ]; then + $DEBUG git -C $repo add -f $package/$i + fi + done + + + if [ $has_git -gt 0 ]; then + $DEBUG git -C $repo commit -e -m "adopt: ${package%%/*}" + fi +} + +[ $# -ge 2 ] && adopt "$@" || cat < Date: Fri, 20 Jun 2025 21:04:23 +0000 Subject: [PATCH 2/8] Adding git-adopt man md --- man/git-adopt.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 man/git-adopt.md diff --git a/man/git-adopt.md b/man/git-adopt.md new file mode 100644 index 00000000..5ba4dca1 --- /dev/null +++ b/man/git-adopt.md @@ -0,0 +1,61 @@ +git-adopt(1) -- Move each file into repo and symlink it back in place +================================ + +## SYNOPSIS + +`git adopt` [-d] <pkg> <files>... + +## DESCRIPTION + +For each file specified: + +1. Move it to the pkg folder inside a repo +2. Create a symlink pointing to that +3. Commit the new files. + +Any necessary subfolders will also be created automatically. + +## OPTIONS + + -d + + Dry run - output shell commands instead of executing. + +## EXAMPLES + +``` +# Minimal setup +git init -b `whoami`@`hostname` .dotfiles +git adopt -d bash .bashrc +git adopt bash .bashrc +``` + +## GIT CONFIGS + +You can customize the adoption repo and target directories via git config options + + $ git config --global add adopt.repo + +The default repo path is `$HOME/.dotfiles`. + + $ git config --global add adopt.target + +The default target is `$HOME`. + +Of course, the user's git config is itself a file that can be tracked via `git-adopt`: + + $ git adopt git .config/git/config + +## AUTHOR + +Written by Neal Fultz . + +## REPORTING BUGS + +<> + +## SEE ALSO + +<> +<> +stow(8) From 09b7c4b0a8608751ec7d45b2b1f6cd990cf58ba6 Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:10:26 +0000 Subject: [PATCH 3/8] Adding git-adopt built documentation --- man/git-adopt.1 | 58 ++++++++++++++++++ man/git-adopt.html | 150 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 man/git-adopt.1 create mode 100644 man/git-adopt.html diff --git a/man/git-adopt.1 b/man/git-adopt.1 new file mode 100644 index 00000000..a5da0095 --- /dev/null +++ b/man/git-adopt.1 @@ -0,0 +1,58 @@ +.\" generated with Ronn-NG/v0.10.1 +.\" http://github.com/apjanke/ronn-ng/tree/0.10.1 +.TH "GIT\-ADOPT" "1" "June 2025" "" "Git Extras" +.SH "NAME" +\fBgit\-adopt\fR \- Move each file into repo and symlink it back in place +.SH "SYNOPSIS" +\fBgit adopt\fR [\-d] \|\.\|\.\|\. +.SH "DESCRIPTION" +For each file specified: +.IP "1." 4 +Move it to the pkg folder inside a repo +.IP "2." 4 +Create a symlink pointing to that +.IP "3." 4 +Commit the new files\. +.IP "" 0 +.P +Any necessary subfolders will also be created automatically\. +.SH "OPTIONS" +\-d +.P +Dry run \- output shell commands instead of executing\. +.SH "EXAMPLES" +.nf +# Minimal setup +git init \-b `whoami`@`hostname` \.dotfiles +git adopt \-d bash \.bashrc +git adopt bash \.bashrc +.fi +.SH "GIT CONFIGS" +You can customize the adoption repo and target directories via git config options +.IP "" 4 +.nf +$ git config \-\-global add adopt\.repo +.fi +.IP "" 0 +.P +The default repo path is \fB$HOME/\.dotfiles\fR\. +.IP "" 4 +.nf +$ git config \-\-global add adopt\.target +.fi +.IP "" 0 +.P +The default target is \fB$HOME\fR\. +.P +Of course, the user's git config is itself a file that can be tracked via \fBgit\-adopt\fR: +.IP "" 4 +.nf +$ git adopt git \.config/git/config +.fi +.IP "" 0 +.SH "AUTHOR" +Written by Neal Fultz \fInfultz@gmail\.com\fR\. +.SH "REPORTING BUGS" +<\fIhttps://github\.com/tj/git\-extras/issues\fR> +.SH "SEE ALSO" +<\fIhttps://github\.com/tj/git\-extras\fR> <\fIhttps://dotfiles\.github\.io/\fR> stow(8) diff --git a/man/git-adopt.html b/man/git-adopt.html new file mode 100644 index 00000000..54f77ead --- /dev/null +++ b/man/git-adopt.html @@ -0,0 +1,150 @@ + + + + + + git-adopt(1) - Move each file into repo and symlink it back in place + + + + +
+ + + +
    +
  1. git-adopt(1)
  2. +
  3. Git Extras
  4. +
  5. git-adopt(1)
  6. +
+ + + +

NAME

+

+ git-adopt - Move each file into repo and symlink it back in place +

+

SYNOPSIS

+ +

git adopt [-d] <pkg> <files>...

+ +

DESCRIPTION

+ +

For each file specified:

+ +
    +
  1. Move it to the pkg folder inside a repo
  2. +
  3. Create a symlink pointing to that
  4. +
  5. Commit the new files.
  6. +
+ +

Any necessary subfolders will also be created automatically.

+ +

OPTIONS

+ +

-d

+ +

Dry run - output shell commands instead of executing.

+ +

EXAMPLES

+ +
# Minimal setup
+git init -b `whoami`@`hostname` .dotfiles
+git adopt -d bash .bashrc
+git adopt bash .bashrc
+
+ +

GIT CONFIGS

+ +

You can customize the adoption repo and target directories via git config options

+ +
$ git config --global add adopt.repo <repo>
+
+ +

The default repo path is $HOME/.dotfiles.

+ +
$ git config --global add adopt.target <target>
+
+ +

The default target is $HOME.

+ +

Of course, the user's git config is itself a file that can be tracked via git-adopt:

+ +
$ git adopt git .config/git/config
+
+ +

AUTHOR

+ +

Written by Neal Fultz nfultz@gmail.com.

+ +

REPORTING BUGS

+ +

<https://github.com/tj/git-extras/issues>

+ +

SEE ALSO

+ +

<https://github.com/tj/git-extras> +<https://dotfiles.github.io/> +stow(8)

+ +
    +
  1. +
  2. June 2025
  3. +
  4. git-adopt(1)
  5. +
+ +
+ + From 00aadf7ffb7fd1cf19e554afef11cfd024321bfb Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:12:33 +0000 Subject: [PATCH 4/8] Adding git-adopt to Commands.md --- Commands.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Commands.md b/Commands.md index fa596142..954c02c5 100644 --- a/Commands.md +++ b/Commands.md @@ -1,5 +1,6 @@ - [`git abort`](#git-abort) + - [`git adopt`](#git-adopt) - [`git alias`](#git-alias) - [`git archive-file`](#git-archive-file) - [`git authors`](#git-authors) @@ -1632,6 +1633,10 @@ Note above, that because of the `--newer` flag, the file `git-alias` was not tou Abort current revert, rebase, merge or cherry-pick, without the need to find exact command in history. +## git adopt + +Move each file into repo and symlink it back in place. Handy for dotfiles. + ## git magic Commits changes with a generated message. From 4d594b6e9f1de36f24d21df87d34bb000c3c6262 Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:16:49 +0000 Subject: [PATCH 5/8] Update etc/git-extras-completion --- etc/git-extras-completion.zsh | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/git-extras-completion.zsh b/etc/git-extras-completion.zsh index 13957f06..103e468c 100644 --- a/etc/git-extras-completion.zsh +++ b/etc/git-extras-completion.zsh @@ -390,6 +390,7 @@ zstyle -g existing_user_commands ':completion:*:*:git:*' user-commands zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \ alias:'define, search and show aliases' \ abort:'abort current revert, merge, rebase, or cherry-pick process' \ + adopt:'move files into repo and symlink back' \ archive-file:'export the current head of the git repository to an archive' \ authors:'generate authors report' \ browse:'open repo website in browser' \ From e5faebdbcee89a4dc519e3912c68e98a7fd414cb Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:33:25 +0000 Subject: [PATCH 6/8] Test for git-adopt --- tests/git-adopt.bats | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/git-adopt.bats diff --git a/tests/git-adopt.bats b/tests/git-adopt.bats new file mode 100644 index 00000000..945a38c0 --- /dev/null +++ b/tests/git-adopt.bats @@ -0,0 +1,23 @@ +# shellcheck shell=bash + +source "$BATS_TEST_DIRNAME/test_util.sh" + + +## Dry run does not need actual files etc +@test "works with -d" { + run git adopt -d foo foo bar/baz + + assert_line -n 1 -e 'mkdir -p' + assert_line -n 2 -e 'mkdir -p' + assert_line -n 3 -e 'mv foo' + assert_line -n 4 -e 'ln -rs' + assert_line -n 5 -e 'git -C .* add' + assert_line -n 6 -e 'mkdir -p' + assert_line -n 7 -e 'mv bar/baz' + assert_line -n 8 -e 'ln -rs' + assert_line -n 9 -e 'git -C .* add' + assert_line -n 10 -e 'git -C .* commit -e -m adopt: foo' + assert_success + +} + From a8bad744ac83be70f70d3505f32dd24a7de6dec6 Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:41:25 +0000 Subject: [PATCH 7/8] Fix tests/git-adopt off-by-one --- tests/git-adopt.bats | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/git-adopt.bats b/tests/git-adopt.bats index 945a38c0..d8bba352 100644 --- a/tests/git-adopt.bats +++ b/tests/git-adopt.bats @@ -8,15 +8,14 @@ source "$BATS_TEST_DIRNAME/test_util.sh" run git adopt -d foo foo bar/baz assert_line -n 1 -e 'mkdir -p' - assert_line -n 2 -e 'mkdir -p' - assert_line -n 3 -e 'mv foo' - assert_line -n 4 -e 'ln -rs' - assert_line -n 5 -e 'git -C .* add' - assert_line -n 6 -e 'mkdir -p' - assert_line -n 7 -e 'mv bar/baz' - assert_line -n 8 -e 'ln -rs' - assert_line -n 9 -e 'git -C .* add' - assert_line -n 10 -e 'git -C .* commit -e -m adopt: foo' + assert_line -n 2 -e 'mv foo' + assert_line -n 3 -e 'ln -rs' + assert_line -n 4 -e 'git -C .* add' + assert_line -n 5 -e 'mkdir -p' + assert_line -n 6 -e 'mv bar/baz' + assert_line -n 7 -e 'ln -rs' + assert_line -n 8 -e 'git -C .* add' + assert_line -n 9 -e 'git -C .* commit -e -m adopt: foo' assert_success } From a2912ed0cf6ac1d53640f7040a5ea2511447008d Mon Sep 17 00:00:00 2001 From: Neal Fultz Date: Fri, 20 Jun 2025 21:56:09 +0000 Subject: [PATCH 8/8] Update index.txt also --- man/index.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/man/index.txt b/man/index.txt index 4f24ad00..3b8424ef 100644 --- a/man/index.txt +++ b/man/index.txt @@ -1,5 +1,6 @@ # manuals git-abort(1) git-abort +git-adopt(1) git-adopt git-alias(1) git-alias git-archive-file(1) git-archive-file git-authors(1) git-authors