3 回答

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊
120000
git ls-files -s | awk '/120000/{print $4}'
git update-index --assume-unchanged
.git/info/exclude
.

TA貢獻(xiàn)1839條經(jīng)驗(yàn) 獲得超15個(gè)贊
建議的解決方案確實(shí)有一些缺點(diǎn),主要是因?yàn)榇鎯?chǔ)庫污染的可能性增加,或者在文件處于“Windows符號(hào)鏈接”狀態(tài)時(shí)不小心添加重復(fù)文件。(下文“限制”一節(jié)將對(duì)此作更多介紹。) 是的,結(jié)帳后腳本是可實(shí)現(xiàn)的!也許不是作為一個(gè)字面上的帖子- git checkout
步驟,但是下面的解決方案已經(jīng)很好地滿足了我的需求,所以不需要一個(gè)文字的簽出腳本。 是!
解決辦法:
120000
在Windows上創(chuàng)建Git符號(hào)鏈接
git config --global alias.add-symlink '!'"$(cat <<'ETX' __git_add_symlink() { if [ $# -ne 2 ] || [ "$1" = "-h" ]; then printf '%b\n' \ 'usage: git add-symlink <source_file_or_dir> <target_symlink>\n' \ 'Create a symlink in a git repository on a Windows host.\n' \ 'Note: source MUST be a path relative to the location of target' [ "$1" = "-h" ] && return 0 || return 2 fi source_file_or_dir=${1#./} source_file_or_dir=${source_file_or_dir%/} target_symlink=${2#./} target_symlink=${target_symlink%/} target_symlink="${GIT_PREFIX}${target_symlink}" target_symlink=${target_symlink%/.} : "${target_symlink:=.}" if [ -d "$target_symlink" ]; then target_symlink="${target_symlink%/}/${source_file_or_dir##*/}" fi case "$target_symlink" in (*/*) target_dir=${target_symlink%/*} ;; (*) target_dir=$GIT_PREFIX ;; esac target_dir=$(cd "$target_dir" && pwd) if [ ! -e "${target_dir}/${source_file_or_dir}" ]; then printf 'error: git-add-symlink: %s: No such file or directory\n' \ "${target_dir}/${source_file_or_dir}" >&2 printf '(Source MUST be a path relative to the location of target!)\n' >&2 return 2 fi git update-index --add --cacheinfo 120000 \ "$(printf '%s' "$source_file_or_dir" | git hash-object -w --stdin)" \ "${target_symlink}" \ && git checkout -- "$target_symlink" \ && printf '%s -> %s\n' "${target_symlink#$GIT_PREFIX}" "$source_file_or_dir" \ || return $? } __git_add_symlink ETX )"
用法: git add-symlink <source_file_or_dir> <target_symlink>
,其中對(duì)應(yīng)于源文件或目錄的參數(shù)必須采用路徑的形式。 相對(duì)于目標(biāo)符號(hào)鏈接。您可以按照通常使用的方式使用此別名。 ln
.例如,存儲(chǔ)庫樹: dir/ dir/foo/ dir/foo/bar/ dir/foo/bar/baz (file containing "I am baz") dir/foo/bar/lnk_file (symlink to ../../../file) file (file containing "I am file") lnk_bar (symlink to dir/foo/bar/)
可以按以下方式在Windows上創(chuàng)建: git init mkdir -p dir/foo/bar/ echo "I am baz" > dir/foo/bar/baz echo "I am file" > file git add -A git commit -m "Add files" git add-symlink ../../../file dir/foo/bar/lnk_file git add-symlink dir/foo/bar/ lnk_bar git commit -m "Add symlinks"
用NTFS硬鏈+結(jié)取代git符號(hào)
git config --global alias.rm-symlinks '!'"$(cat <<'ETX' __git_rm_symlinks() { case "$1" in (-h) printf 'usage: git rm-symlinks [symlink] [symlink] [...]\n' return 0 esac ppid=$$ case $# in (0) git ls-files -s | grep -E '^120000' | cut -f2 ;; (*) printf '%s\n' "$@" ;; esac | while IFS= read -r symlink; do case "$symlink" in (*/*) symdir=${symlink%/*} ;; (*) symdir=. ;; esac git checkout -- "$symlink" src="${symdir}/$(cat "$symlink")" posix_to_dos_sed='s_^/\([A-Za-z]\)_\1:_;s_/_\\\\_g' doslnk=$(printf '%s\n' "$symlink" | sed "$posix_to_dos_sed") dossrc=$(printf '%s\n' "$src" | sed "$posix_to_dos_sed") if [ -f "$src" ]; then rm -f "$symlink" cmd //C mklink //H "$doslnk" "$dossrc" elif [ -d "$src" ]; then rm -f "$symlink" cmd //C mklink //J "$doslnk" "$dossrc" else printf 'error: git-rm-symlink: Not a valid source\n' >&2 printf '%s =/=> %s (%s =/=> %s)...\n' \ "$symlink" "$src" "$doslnk" "$dossrc" >&2 false fi || printf 'ESC[%d]: %d\n' "$ppid" "$?" git update-index --assume-unchanged "$symlink" done | awk ' BEGIN { status_code = 0 } /^ESC\['"$ppid"'\]: / { status_code = $2 ; next } { print } END { exit status_code } ' } __git_rm_symlinks ETX )" git config --global alias.rm-symlink '!git rm-symlinks' # for back-compat.
用法: git rm-symlinks [symlink] [symlink] [...]
這個(gè)別名可以一次地刪除git符號(hào)鏈接。Symlink將替換為NTFS硬鏈接(在文件中)或NTFS連接(在目錄中)。與“真”NTFS符號(hào)鏈接相比,使用硬鏈接+連接的好處是 要?jiǎng)?chuàng)建UAC權(quán)限,不需要經(jīng)過提升的UAC權(quán)限。要從子模塊中刪除符號(hào)鏈接,只需使用git內(nèi)置的支持迭代它們: git submodule foreach --recursive git rm-symlinks
但是,對(duì)于每一次如此激烈的行動(dòng),有一個(gè)逆轉(zhuǎn)是很好的. 在Windows上恢復(fù)Git符號(hào)鏈接
git config --global alias.checkout-symlinks '!'"$(cat <<'ETX' __git_checkout_symlinks() { case "$1" in (-h) printf 'usage: git checkout-symlinks [symlink] [symlink] [...]\n' return 0 esac case $# in (0) git ls-files -s | grep -E '^120000' | cut -f2 ;; (*) printf '%s\n' "$@" ;; esac | while IFS= read -r symlink; do git update-index --no-assume-unchanged "$symlink" rmdir "$symlink" >/dev/null 2>&1 git checkout -- "$symlink" printf 'Restored git symlink: %s -> %s\n' "$symlink" "$(cat "$symlink")" done } __git_checkout_symlinks ETX )" git config --global alias.co-symlinks '!git checkout-symlinks'
用法: git checkout-symlinks [symlink] [symlink] [...]
,這會(huì)使 git rm-symlinks
,有效地將存儲(chǔ)庫恢復(fù)到其自然狀態(tài)(除了您的更改之外, 應(yīng)保持原封不動(dòng))。 對(duì)于子模塊: git submodule foreach --recursive git checkout-symlinks
限制:
路徑中有空格的目錄/文件/符號(hào)鏈接應(yīng)該可以工作。但是標(biāo)簽還是新行?YMMV…(我的意思是:不要那樣做,因?yàn)樗?/trans>不會(huì) 工作) 如果你或其他人忘了 git checkout-symlinks
在做一些有可能造成廣泛后果的事情之前 git add -A
,本地存儲(chǔ)庫可能會(huì)以 污染狀態(tài)。使用我們以前的“示例回購(gòu)”: echo "I am nuthafile" > dir/foo/bar/nuthafile echo "Updating file" >> file git add -A git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: dir/foo/bar/nuthafile # modified: file # deleted: lnk_bar # POLLUTION # new file: lnk_bar/baz # POLLUTION # new file: lnk_bar/lnk_file # POLLUTION # new file: lnk_bar/nuthafile # POLLUTION #
哇哦.。 因此,在構(gòu)建項(xiàng)目之前和之后,而不是在簽出或推送之前,將這些別名作為Windows用戶執(zhí)行的步驟是很好的。但每一種情況都是不同的。這些別名對(duì)我來說已經(jīng)足夠有用了,所以不需要真正的結(jié)帳解決方案。
參考資料:
POSIX的遵守情況(嗯,除了那些 mklink
當(dāng)然) 巴什主義 !支持包含空格的目錄和文件。 零和非零退出狀態(tài)代碼(分別用于通信請(qǐng)求的命令的成功/失敗)現(xiàn)在被正確保存/返回。 這個(gè) add-symlink
別名現(xiàn)在更像 并且可以在存儲(chǔ)庫中的任何目錄中使用,而不僅僅是存儲(chǔ)庫的根目錄。 這個(gè) rm-symlink
別名(單數(shù))已被 rm-symlinks
別名(復(fù)數(shù)),它現(xiàn)在接受多個(gè)參數(shù)(或者根本不接受參數(shù),它像以前一樣在存儲(chǔ)庫中查找所有的符號(hào)鏈接),用于選擇性地將git符號(hào)鏈接轉(zhuǎn)換為NTFS硬鏈接+連接。 這個(gè) checkout-symlinks
別名還被更新為接受多個(gè)參數(shù)(或根本不接受,=All),以選擇性地逆轉(zhuǎn)上述轉(zhuǎn)換。
最后注:
. ./git-win-symlinks.sh
- 3 回答
- 0 關(guān)注
- 919 瀏覽
添加回答
舉報(bào)