diff options
| author | Martin Afanasjew | 2016-05-31 17:11:57 +0200 |
|---|---|---|
| committer | Martin Afanasjew | 2016-05-31 17:11:57 +0200 |
| commit | b9552a5fbf3772b408cdb25c3a545bb1444ba8ff (patch) | |
| tree | 9e5f96a4f531428c9cbce65e1283c556465abe65 /Library | |
| parent | 0a7fcf29797469f7cd9eaa653ba3e54e412e4583 (diff) | |
| download | brew-b9552a5fbf3772b408cdb25c3a545bb1444ba8ff.tar.bz2 | |
download_strategy: fix git submodule references (#303)
Some Git versions create absolute `gitdir:` pointers in a submodule's
`.git` file, which can be problematic once the resource is staged and
causes various Git operations for those submodules to fail. Work around
this issue by fixing the submodule `.git` files after submodule update.
See Homebrew/homebrew-core#1520 for details and an affected formula.
Diffstat (limited to 'Library')
| -rw-r--r-- | Library/Homebrew/download_strategy.rb | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index bd12524fa..19ce95b48 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -696,6 +696,39 @@ class GitDownloadStrategy < VCSDownloadStrategy def update_submodules quiet_safe_system "git", "submodule", "foreach", "--recursive", "git submodule sync" quiet_safe_system "git", "submodule", "update", "--init", "--recursive" + fix_absolute_submodule_gitdir_references! + end + + def fix_absolute_submodule_gitdir_references! + # When checking out Git repositories with recursive submodules, some Git + # versions create `.git` files with absolute instead of relative `gitdir:` + # pointers. This works for the cached location, but breaks various Git + # operations once the affected Git resource is staged, i.e. recursively + # copied to a new location. (This bug was introduced in Git 2.7.0 and fixed + # in 2.8.3. Clones created with affected version remain broken.) + # See https://github.com/Homebrew/homebrew-core/pull/1520 for an example. + submodule_dirs = Utils.popen_read( + "git", "submodule", "--quiet", "foreach", "--recursive", "pwd") + submodule_dirs.lines.map(&:chomp).each do |submodule_dir| + work_dir = Pathname.new(submodule_dir) + + # Only check and fix if `.git` is a regular file, not a directory. + dot_git = work_dir/".git" + next unless dot_git.file? + + git_dir = dot_git.read.chomp[/^gitdir: (.*)$/, 1] + if git_dir.nil? + onoe "Failed to parse '#{dot_git}'." if ARGV.homebrew_developer? + next + end + + # Only attempt to fix absolute paths. + next unless git_dir.start_with?("/") + + # Make the `gitdir:` reference relative to the working directory. + relative_git_dir = Pathname.new(git_dir).relative_path_from(work_dir) + dot_git.atomic_write("gitdir: #{relative_git_dir}\n") + end end end |
