This repository has been archived by the owner on Dec 11, 2019. It is now read-only.
forked from felipec/git-remote-hg
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Felipe's git-marks-check to the repository, for convenience
This doesn't solve the actual issues, but helps mitigate them in many cases. I am not completely sure what the "actual" issues are, but one seems to be that it is apparently relatively easy to end up with a corrupt marks file (and indeed, the code loading / saving marks does not attempt to be particular robust). The other problem hinted at in issue #4 seems to be when tips in the remote hg repository change, then this seems to also cause troubles. See also: felipec#4 felipec#10
- Loading branch information
Showing
1 changed file
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#!/usr/bin/env ruby | ||
|
||
require 'json' | ||
|
||
$fix = false | ||
$verbose = false | ||
$git_marks = {} | ||
$r_marks = {} | ||
$mode = 'hg' | ||
|
||
# Parse arguments | ||
ARGV.delete_if do |cur| | ||
next false if cur[0] != '-' | ||
case cur | ||
when /^-f$/, /^--fix$/ | ||
$fix = true | ||
true | ||
when /^-v$/, /^--verbose$/ | ||
$verbose = true | ||
true | ||
when /^-m(.+)$/, /^--mode=(.+)$/ | ||
$mode = $1 | ||
true | ||
end | ||
end | ||
|
||
$remote = ARGV[0] | ||
|
||
$dir = File.join('.git', $mode, $remote) | ||
$git_file = File.join($dir, 'marks-git') | ||
$r_file = File.join($dir, 'marks-' + $mode) | ||
|
||
# TODO | ||
$r_file = File.join($dir, 'marks-int') if $mode == 'bzr' | ||
|
||
# Get git marks | ||
File.open($git_file).each do |l| | ||
if l =~ /:(\d+) (\h+)$/ | ||
$git_marks[$1.to_i] = $2 | ||
end | ||
end | ||
|
||
# Remove non commit objects | ||
File.popen(%w[git cat-file --batch-check], 'r+') do |p| | ||
$git_marks.each do |mark,id| | ||
p.write(id + "\n") | ||
if p.readline =~ /(\h+) (\w+) (\d+)/ | ||
type = $2 | ||
$git_marks.delete(mark) unless type == 'commit' | ||
end | ||
end | ||
end | ||
|
||
# Remove notes | ||
File.popen(%W[git rev-list refs/notes/#{$mode}], 'r', :err => File::NULL) do |p| | ||
p.each do |l| | ||
$git_marks.delete_if { |mark,id| id == l.chomp } | ||
end | ||
end | ||
|
||
# Get remote marks | ||
r_data = JSON.parse(File.read($r_file)) | ||
$r_marks = r_data['marks'].invert | ||
|
||
r_missing = $git_marks.reject { |mark,id| $r_marks[mark] } | ||
git_missing = $r_marks.reject { |mark,id| $git_marks[mark] } | ||
|
||
if $verbose | ||
r_missing.each do |mark,id| | ||
puts "Missing %s (%d) from #{$mode}" % [id, mark] | ||
end | ||
git_missing.each do |mark,id| | ||
puts "Missing %s (%d) from git" % [id, mark] | ||
end | ||
end | ||
|
||
if $fix | ||
# Fix remote marks | ||
r_data['marks'].delete_if { |mark,id| git_missing.has_key?(id) } | ||
File.write($r_file, r_data.to_json) | ||
|
||
# Fix git marks | ||
File.open($git_file, 'w') do |f| | ||
$git_marks.each do |mark,id| | ||
next if r_missing.has_key?(mark) | ||
f.puts ':%d %s' % [mark, id] | ||
end | ||
end | ||
end | ||
|
||
if r_missing.empty? and git_missing.empty? | ||
puts 'Everything OK' | ||
else | ||
puts 'Issues detected' | ||
exit 1 | ||
end |