現象
includeIfをしようしてgitconfigを切り替えている場合に、cargo new <プロジェクト名>をするとCargo.tomlのauthorsに切り替えたgitconfigの情報が入らずに、globalで設定しているgitconfig情報が入ってしまう。
例えばglobalのgitconfigの設定が
username: global_takoyaki
includeIfで設定したgitconfigの設定が
username: local_takoyaki
とした場合に、切り替わるはずのディレクトリでcargo new <プロジェクト名>をするとglobal_takoyakiが設定されてしまう。
local_takoyakiにしたい!
追跡
GitHub - rust-lang/cargo: The Rust package manager
ここからCargoのRepoがあるので追跡してみる。
src/cargo/ops配下にCargoのコマンドのファイルがあります。
src/cargo/ops/cargo_new.rs
にはcargo newとcargo initのコマンド記述があります。
これらのメソッドは共通して
fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()>
を呼び出しており、ここでgit initやCargo.tomlの一連の処理を行なっているようです。
特にgit initの処理は
fn init_vcs(path: &Path, vcs: VersionControl, config: &Config) -> CargoResult<()>
を呼び出しており、そこからバージョン管理のツールごとに場合分けを行なっています。
Gitの処理はsrc/cargo/util/vcs.rsのGitRepo構造体で管理されており、実態はlibgit2 for Rustが使用されているようです。
gitのincludeIfの仕様
対象のフォルダへ行ってgit config user.nameを実行しただけでは、globalのgitconfigが参照される。
git initをして、gitリポジトリが生成されてからgit config user.nameを実行するとincludeIfのgitconfigが参照される。
gitのincludeIfで指定したgitconfigが反映されない理由
原因はgitが生成されるディレクトリからgitconfigを取得しようとしていないためです。
例えば、takoyakiフォルダでCargo new <プロジェクト名>とした時の現在のディレクトリはtakoyakiなので、gitはtakoyakiフォルダにgitがないのでグローバルの設定を取得しにいこうとします。
かなり雑にCargoのソースコード修正
impl GitRepo {
pub fn init(path: &Path, _: &Path) -> CargoResult<GitRepo> {
let _ = env::set_current_dir(path).is_ok();
git2::Repository::init(path)?;
Ok(GitRepo)
}
}
let _ = env::set_current_dir(path).is_ok();
git initの処理される前に、現在の作業ディレクトリをgitが生成されるディレクトリに変更すれば、includeIfで設定したgitconfigが反映されます。
※ かなり雑です。何も考慮してません。
代替案
mkdir sample
cd sample
cargo init .
でcargo initを使用する方法ならgitの生成されるディレクトと作業ディレクトリが一致するので、想定のgitconfigの情報が反映されます。
修正すべきか?
微妙な気がします。
一応cargoのヘルプをみると以下のように記載されていて、
USAGE:
cargo new [OPTIONS] <path>
OPTIONS:
-q, --quiet No output printed to stdout
--registry <REGISTRY> Registry to use
--vcs <VCS> Initialize a new repository for the given version control system (git, hg, pijul, or
fossil) or do not initialize any version control at all (none), overriding a global
configuration. [possible values: git, hg, pijul, fossil, none]
--bin Use a binary (application) template [default]
--lib Use a library template
--edition <YEAR> Edition to set for the crate generated [possible values: 2015, 2018]
--name <NAME> Set the resulting package name, defaults to the directory name
-v, --verbose Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
-Z <FLAG>... Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Prints help information
ARGS:
<path>
と書いてあるので、大丈夫と言えば、大丈夫なのですが、意識しないと、うっかりとglobalの方のgitconfigがtomlに反映されてしまうので、個人的には自動でincludeIfで設定したgitconfigを参照してほしい気がします。