在.gitignore中,結合使用/*
和!filename
的語法,可以達到除特定文件或目錄外全部忽略的目的。但當希望不忽略的文件或目錄在二級或多級目錄下時,如果這樣寫
/*
!/sub/subsub/
是不能達到預期效果的,這會導致根目錄下的全部文件被忽略,包括/sub/subsub/。因為.gitignore語法中,!filename
只能對同級的/*
生效,因此如果要在根目錄中排除多級目錄中的文件,需要重復地指明每一級目錄的忽略規則。下面以忽略根目錄中的全部文件,但不忽略/1st/2nd/目錄中的tgt文件為例:
/*
!/1st/2nd/tgt #Wrong! Still ignored.
/*
!/1st/
/1st/*
!/1st/2nd/
/1st/2nd/*
!/1st/2nd/tgt
#Correct! Specify rules for each directory.
當目錄變得足夠深,或者這樣的目錄很多時,可以預料編寫.gitignore的工作會變得極其繁復而易錯。為此,我寫了一段Javascript腳本以自動化這一流程:
str => {
let arr = str.split("/");
arr = arr.map((e, i) => arr.slice(0, i+1).join("/"));
arr.shift();
const trail = `!${arr.pop()}`;
arr = arr.map(e => `!${e}/\n${e}/*\n`);
return arr.join("") + trail;
}
使用示例:
(str => {
let arr = str.split("/");
arr = arr.map((e, i) => arr.slice(0, i+1).join("/"));
arr.shift();
const trail = `!${arr.pop()}`;
arr = arr.map(e => `!${e}/\n${e}/*\n`);
return arr.join("") + trail;
})("/1st/2nd/tgt")
/*
Output:
!/1st/
/1st/*
!/1st/2nd/
/1st/2nd/*
!/1st/2nd/tgt
*/