GNU Stowの「--adopt」オプションとは反対ですか?

GNU Stowの「--adopt」オプションとは反対ですか?

私はそれを使用していますGNUストー私のドットファイルを次のように管理してくださいこのガイド。これは、コンピュータに既存のドットファイルがない場合に有効です。たとえば、ファイルが存在しない場合は、~/.config/foo.cfg次が正常に動作します。

~/.dotfiles$ mkdir -p foo/.config
~/.dotfiles$ echo My config > foo/.config/foo.cfg
~/.dotfiles$ stow foo
~/.dotfiles$ ls -l ~/.config
lrwxrwxrwx 1 user group 21 Dec  6 19:03 ~/.config -> .dotfiles/foo/.config

~/.config/foo.cfgすでに存在する場合、それほど単純ではありません。

~/.dotfiles$ stow foo
WARNING! stowing bar would cause conflicts:
  * existing target is neither a link nor a directory: foo.cfg
All operations aborted.

これまで私が見つけた唯一の解決策は、.dotファイルを手動で削除し~/.config/foo.cfgて再実行することですstow foo。 stow を使用してポイントファイルを管理する目的。

ストウには--adopt選択権がありました。これは、保存されたファイルをコンピュータ上のstow --adopt foo既存のfooファイルに置き換えてシンボリックリンクを作成することです。foo私が探しているのは反対の効果を得る方法です。マシンの.dotfilesをstashバージョンへのシンボリックリンクに置き換えることで、Gitリポジトリのstash dotファイルを使用して新しいマシンをプロビジョニングできます。

これはStowを使用してポイントファイルを管理するための当然の要件のようです。何かが欠けていたり、問題がすでに解決されているような気がします。

どんなアイデアがありますか?

答え1

私は同じ制限に遭遇し、--adoptこのオプションとうまく機能するワークフローを見つけました。で述べたように文書を保存:

...ターゲットツリーのファイル(内容はstowパッケージのインストールイメージの対応するバージョンと異なる場合があります)をパッケージに適用し、stowパッケージ内で "git diff ..."などのコマンドを実行します。内容は比較され、最後に保持されるか(例: "git commit ..."を介して)削除されます( "git checkout HEAD ...")。

私のワークフロー:

  1. stowこのオプションを使用して実行してください--adopt
  2. .を使用して、「採用された」ファイルをマイストアの元のファイルと比較しますgit diff
  3. git reset --hardディレクトリ全体を最後のコミットされた状態に復元するには、「採用された」ファイルから発生したすべての変更を削除してください。

例:

# Running from inside .dotfiles repository
❯ tree . -a
.
├── bash
│   ├── .bashrc
│   └── .xprofile

# Stow bash folder as usual and note conflicts (.bashrc in this case)
❯ stow bash
WARNING! stowing bash would cause conflicts:
  * existing target is neither a link nor a directory: .bashrc
All operations aborted.
e conflicts

# Rerun Stow with --adopt flag to place conflicting files in .dotfiles repo (no warnings)
❯ stow bash --adopt

# Use git diff to compare adopted and committed file
❯ git diff
diff --git a/bash/.bashrc b/bash/.bashrc
index cbd6843..0ac2879 100644
--- a/bash/.bashrc
+++ b/bash/.bashrc
@@ -1,121 +1 @@
... Line changes are listed ...

# Discard adopted file and revert back to contents as per last commit
❯ git reset --hard

# Done

私は最初にdotfilesとStowに触れたので、いくつかの制限がありません。これまでの結果に満足しています。

答え2

私は同じ問題に直面しました。私は個人的にAnsibleを使用してすべてのGNU Stowコマンドを自動化します。 Ansibleスクリプトはあなたの要件に正確に合わないかもしれませんが、私のアプローチはさまざまなオプションをナビゲートするのに役立ちます。以下に書かれたAnsible Playbookのシェルコマンドを変更することで、bashで同様のスクリプトを書くことができます。

私のdotfileフォルダは次のように構成されています。 「~/dotfiles/home/」には、「bash」や「zsh」などのサブフォルダ名が含まれています。このコードで dotfile_packages = "~/dotfiles/home/"

これは大量のファイルを無人で削除するため、安全でない方法であることに注意してください。

  - name: Find all dotfiles subfolders
    find:
      paths: "{{ dotfile_packages }}"
      file_type: directory
      recurse: no
    register: dotfile_folders

  - name: Get list of dotfiles to check for GNU Stow conflicts
    shell: find ./home/{{ item }} \( -type f -o -type l \) | sed 's/.\/home\/{{ item }}\///g'
    args:
      chdir: "{{ repo_dir }}"
    register: conflict_files
    with_items: "{{ dotfile_folders.files | map(attribute='path') | list | map('basename') }}"

  - name: Show list of files to be checked for GNU Stow conflicts
    debug:
      msg: "{{ item }}" 
    with_items: "{{ conflict_files.results | map(attribute='stdout_lines') | list | flatten }}"

  # If we don't unstow first, the delete operation erases any previously stowed dotfile sources.
  # Ignoring errors because sometimes unstow will fail to finish because OS added some untracked files.
  - name: Unstow all packages deleting conflict files.
    shell: stow -D -d {{ dotfile_packages }} -t ~/ {{ item }}
    with_items: "{{ dotfile_folders.files | map(attribute='path') | list | map('basename') }}"
    ignore_errors: yes

  - name: Delete conflicting files
    shell: rm -rf ~/{{ item }}
    with_items: "{{ conflict_files.results | map(attribute='stdout_lines') | list | flatten }}"

  - name: Symlink dotfiles
    shell: stow -d {{ dotfile_packages }} -t ~/ {{ item }}
    with_items: "{{ dotfile_folders.files | map(attribute='path') | list | map('basename') }}"

ここで私のドットファイルで使用されているコードの断片を見ることができます。

答え3

私はstowの使い方を次のようにパッケージ化してこれを行いました。ファイルの生成(バックアップ対象の確認)

# List of packages to manage with stow
PACKAGES ?= $(filter-out .git .github, $(wildcard */))

# Directory where stow will look for packages. Default is current directory
DIR ?= $$(pwd)

# Default location where stow will create symbolic links
TARGET ?= ${HOME}

IGNORE ?= \.DS_Store

# Stow command to create links
STOW_CMD = stow \
    --dir="${DIR}" \
    --target="${TARGET}" \
    --ignore="${IGNORE}" \
    --ignore="\.DS_Store" \
    --ignore=".*\.template" \
    --no-folding \
    --verbose

# Function to backup existing files for a specific package if they exist
define backup_if_exists
    checks=$$(${STOW_CMD} --no --verbose ${1} 2>&1 | \
        egrep '\* existing target is ' | \
        sed 's/  \* existing target is neither a link nor a directory: //'); \
    for file in $$checks; do \
        filepath=${TARGET}/$$file; \
        backup_suffix="backup-$$(date -u +%Y%m%d%H%M%S)"; \
        echo "Creating backup $$filepath.$$backup_suffix"; \
        mv -h "$$filepath" "$$filepath.$$backup_suffix"; \
    done
endef

# Default rule to create symbolic links for all packages
all: stow

# Rule to backup existing configurations
backup:
    @echo "Checking for existing files to backup..."
    @$(foreach package,$(PACKAGES), \
        $(call backup_if_exists,$(package));)

# Rule to link configurations using stow
stow: backup
    @echo "Applying stow for packages..."
    @$(foreach package,${PACKAGES}, \
        $(STOW_CMD) ${package};)

# Rule to remove symbolic links
unstow:
    @echo "Removing stow links for packages..."
    @$(foreach package,$(PACKAGES), \
        $(STOW_CMD) -D $(package);)

# Rule to reapply symbolic links
restow: backup unstow stow

# Rule to display help
help:
    @echo ""
    @echo "\033[1mUSAGE\033[0m"
    @echo ""
    @echo "  make [target]"
    @echo ""
    @echo "\033[1mTARGETS\033[0m"
    @echo ""
    @echo "  stow    - Create symlinks for all packages (default)"
    @echo "  restow  - Reapply symlinks for all packages"
    @echo "  unstow  - Remove symlinks for all packages (\033[31mcaution\033[0m)"
    @echo "  help    - Show this help message"
    @echo ""

.PHONY: all backup stow unstow restow help

このMakefileの機能は何ですか?

  1. 初めてチェックモードを開始
  2. 既存プロジェクトのリスト
  3. バックアップファイル
  4. 発射後退
USAGE

  make [target]

TARGETS

  stow    - Create symlinks for all packages (default)
  restow  - Reapply symlinks for all packages
  unstow  - Remove symlinks for all packages (caution)
  help    - Show this help message

答え4

私は同じ問題に直面しました。以下は試してみると簡単な解決策ですstow config

stow config
# WARNING! stowing config would cause conflicts:
# ...
# All operations aborted.
rsync -a config/ config.bak/ # create a backup; this may not be exactly the right rsync syntax
stow --adopt config.bak      # should take ownership of all existing files
stow -D config.bak           # remove all the symlinks just created
stow config                  # should now work fine
rm -rf config.bak

関連情報