Merge branch 'master' into gettext-cs

This commit is contained in:
serras 2012-01-22 19:19:19 +01:00
commit a06e58b582
78 changed files with 3578 additions and 2022 deletions

5
NEWS
View file

@ -1,10 +1,13 @@
0.8.0 for Linux and Mac (Sat Jan 14): 0.8.0 for Linux and Mac (Sun Jan 22):
Hylke: Hylke:
- Show syncing progress in the status icon - Show syncing progress in the status icon
- Hide dock icon on Mac until you open a window - Hide dock icon on Mac until you open a window
- Update dates in the event log after midnight - Update dates in the event log after midnight
- Don't let git compress already compressed files (.jpg .ogg .zip, etc.) - Don't let git compress already compressed files (.jpg .ogg .zip, etc.)
- Limit git's memory usage
- Ignore history of any added git/hg/bzr repositories, just add the files
- Spin status icon on syncing changes made before startup
0.6.0 for Linux and Mac (Sun Dec 25 2011): 0.6.0 for Linux and Mac (Sun Dec 25 2011):

View file

@ -23,17 +23,17 @@ Requirements:
- git >= 1.7.0 - git >= 1.7.0
- gtk-sharp2 - gtk-sharp2
- gvfs
- intltool
- libnotify
- mono-core >= 2.8 - mono-core >= 2.8
- notify-sharp - notify-sharp
- nautilus-python
- openssh
- pygtk
- webkitgtk
- webkit-sharp - webkit-sharp
Optional:
- nautilus-python
- gvfs
- libappindicator
Run the service, either click the SparkleShare launcher or: Run the service, either click the SparkleShare launcher or:
```bash ```bash
@ -135,11 +135,11 @@ MonoDevelop and start the build.
To create the <tt>SparkleShare.app</tt>, make sure the project is focused and select Project from the menu bar To create the <tt>SparkleShare.app</tt>, make sure the project is focused and select Project from the menu bar
and click <tt>"Create Mac Installer..."</tt>. Make sure to select <tt>"Don't link assemblies"</tt>. and click <tt>"Create Mac Installer..."</tt>. Make sure to select <tt>"Don't link assemblies"</tt>.
Save the <tt>SparkleShare.app</tt> somewhere. Paste the contents of Save the <tt>SparkleShare.app</tt> somewhere. Copy `SparkleShare/Mac/config` to
the following file in `SparkleShare.app/Contents/MonoBundle/config`: `SparkleShare.app/Contents/MonoBundle/config` (adjust the paths to where you saved the .app):
``` ```
https://raw.github.com/gist/1aeffa61bac73fc08eca/0c0f09ef9e36864c35f34fd5e8bf4f99886be193/gistfile1.txt cp SparkleShare/Mac/config SparkleShare.app/Contents/MonoBundle/config
``` ```
Copy `/Library/Frameworks/Mono.framework/Versions/Current/lib/libintl.dylib` to `SparkleShare.app/Contents/Resources` Copy `/Library/Frameworks/Mono.framework/Versions/Current/lib/libintl.dylib` to `SparkleShare.app/Contents/Resources`

View file

@ -22,20 +22,27 @@ namespace SparkleLib {
public class SparkleGit : Process { public class SparkleGit : Process {
public static string ExecPath = null;
public SparkleGit (string path, string args) : base () public SparkleGit (string path, string args) : base ()
{ {
EnableRaisingEvents = true; EnableRaisingEvents = true;
StartInfo.FileName = SparkleBackend.DefaultBackend.Path; StartInfo.FileName = SparkleBackend.DefaultBackend.Path;
StartInfo.Arguments = args;
StartInfo.RedirectStandardOutput = true; StartInfo.RedirectStandardOutput = true;
StartInfo.UseShellExecute = false; StartInfo.UseShellExecute = false;
StartInfo.WorkingDirectory = path; StartInfo.WorkingDirectory = path;
if (!string.IsNullOrEmpty (ExecPath))
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
else
StartInfo.Arguments = args;
} }
new public void Start () new public void Start ()
{ {
SparkleHelpers.DebugInfo ("Cmd", StartInfo.FileName + " " + StartInfo.Arguments); SparkleHelpers.DebugInfo ("Cmd", "git " + StartInfo.Arguments);
base.Start (); base.Start ();
} }
} }

View file

@ -42,20 +42,25 @@ namespace SparkleShare {
public SparkleController () : base () public SparkleController () : base ()
{ {
string content_path = string content_path =
Directory.GetParent (System.AppDomain.CurrentDomain.BaseDirectory) Directory.GetParent (System.AppDomain.CurrentDomain.BaseDirectory).ToString ();
.ToString ();
string app_path = Directory.GetParent (content_path).ToString (); string app_path = Directory.GetParent (content_path).ToString ();
string growl_path = Path.Combine (app_path, "Frameworks", "Growl.framework", "Growl"); string growl_path = Path.Combine (app_path, "Frameworks", "Growl.framework", "Growl");
// Needed for Growl // Needed for Growl
Dlfcn.dlopen (growl_path, 0); Dlfcn.dlopen (growl_path, 0);
NSApplication.Init (); NSApplication.Init ();
// Let's use the bundled git first // Let's use the bundled git first
SparkleBackend.DefaultBackend.Path = SparkleBackend.DefaultBackend.Path =
Path.Combine (NSBundle.MainBundle.ResourcePath, Path.Combine (NSBundle.MainBundle.ResourcePath,
"git", "bin", "git"); "git", "libexec", "git-core", "git");
SparkleGit.ExecPath =
Path.Combine (NSBundle.MainBundle.ResourcePath,
"git", "libexec", "git-core");
} }

View file

@ -59,7 +59,7 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
</Reference> </Reference>
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="SparkleLib, Version=0.6.0.0, Culture=neutral, PublicKeyToken=null"> <Reference Include="SparkleLib, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\SparkleLib.dll</HintPath> <HintPath>..\..\bin\SparkleLib.dll</HintPath>
</Reference> </Reference>
@ -145,42 +145,42 @@
<Content Include="..\..\data\sparkleshare.icns"> <Content Include="..\..\data\sparkleshare.icns">
<Link>sparkleshare.icns</Link> <Link>sparkleshare.icns</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle0-active.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-i-active.png">
<Link>Pixmaps\idle0-active.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-i-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle0.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-i.png">
<Link>Pixmaps\idle0.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-i.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle1-active.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-ii-active.png">
<Link>Pixmaps\idle1-active.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-ii-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle1.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-ii.png">
<Link>Pixmaps\idle1.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-ii.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle2-active.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iii-active.png">
<Link>Pixmaps\idle2-active.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iii-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle2.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iii.png">
<Link>Pixmaps\idle2.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iii.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle3-active.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iiii-active.png">
<Link>Pixmaps\idle3-active.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iiii-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle3.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iiii.png">
<Link>Pixmaps\idle3.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iiii.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle4-active.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iiiii-active.png">
<Link>Pixmaps\idle4-active.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iiiii-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\idle4.png"> <Content Include="..\..\data\icons\process-syncing-sparkleshare-mac-iiiii.png">
<Link>Pixmaps\idle4.png</Link> <Link>Pixmaps\process-syncing-sparkleshare-mac-iiiii.png</Link>
</Content> </Content>
<Content Include="Growl.plist" /> <Content Include="Growl.plist" />
<Content Include="..\..\data\icons\error.png"> <Content Include="..\..\data\icons\sparkleshare-syncing-error-mac.png">
<Link>Pixmaps\error.png</Link> <Link>Pixmaps\sparkleshare-syncing-error-mac.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\error-active.png"> <Content Include="..\..\data\icons\sparkleshare-syncing-error-mac-active.png">
<Link>Pixmaps\error-active.png</Link> <Link>Pixmaps\sparkleshare-syncing-error-mac-active.png</Link>
</Content> </Content>
<Content Include="..\..\data\icons\document-added-12.png"> <Content Include="..\..\data\icons\document-added-12.png">
<Link>Pixmaps\document-added-12.png</Link> <Link>Pixmaps\document-added-12.png</Link>

View file

@ -70,8 +70,8 @@ namespace SparkleShare {
{ {
using (var a = new NSAutoreleasePool ()) using (var a = new NSAutoreleasePool ())
{ {
ErrorImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error.png"); ErrorImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkleshare-syncing-error-mac.png");
ErrorImageActive = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error-active.png"); ErrorImageActive = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkleshare-syncing-error-mac-active.png");
FolderImage = NSImage.ImageNamed ("NSFolder"); FolderImage = NSImage.ImageNamed ("NSFolder");
CautionImage = NSImage.ImageNamed ("NSCaution"); CautionImage = NSImage.ImageNamed ("NSCaution");
SparkleShareImage = NSImage.ImageNamed ("sparkleshare-mac"); SparkleShareImage = NSImage.ImageNamed ("sparkleshare-mac");
@ -111,9 +111,9 @@ namespace SparkleShare {
case IconState.Syncing: case IconState.Syncing:
StateText = _("Syncing… " + StateText = _("Syncing… ") +
Controller.ProgressPercentage + "% " + Controller.ProgressPercentage + "% " +
Controller.ProgressSpeed); Controller.ProgressSpeed;
StateMenuItem.Title = StateText; StateMenuItem.Title = StateText;
@ -342,19 +342,19 @@ namespace SparkleShare {
FrameNumber = 0; FrameNumber = 0;
AnimationFrames = new NSImage [] { AnimationFrames = new NSImage [] {
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle0.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-i.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle1.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-ii.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle2.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iii.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle3.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iiii.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle4.png")) new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iiiii.png"))
}; };
AnimationFramesActive = new NSImage [] { AnimationFramesActive = new NSImage [] {
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle0-active.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-i-active.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle1-active.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-ii-active.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle2-active.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iii-active.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle3-active.png")), new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iiii-active.png")),
new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle4-active.png")) new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-sparkleshare-mac-iiiii-active.png"))
}; };
Timer Animation = new Timer () { Timer Animation = new Timer () {

30
SparkleShare/Mac/config Normal file
View file

@ -0,0 +1,30 @@
<configuration>
<dllmap dll="i:cygwin1.dll" target="libc.dylib" os="!windows" />
<dllmap dll="libc" target="libc.dylib" os="!windows"/>
<dllmap dll="intl" target="libintl.dylib" os="!windows"/>
<dllmap dll="intl" name="bind_textdomain_codeset" target="libc.dylib" os="solaris"/>
<dllmap dll="libintl" name="bind_textdomain_codeset" target="libc.dylib" os="solaris"/>
<dllmap dll="libintl" target="libintl.dylib" os="!windows"/>
<dllmap dll="i:libxslt.dll" target="libxslt.dylib" os="!windows"/>
<dllmap dll="i:odbc32.dll" target="libodbc.dylib" os="!windows"/>
<dllmap dll="i:odbc32.dll" target="libiodbc.dylib" os="osx"/>
<dllmap dll="oci" target="libclntsh.dylib" os="!windows"/>
<dllmap dll="db2cli" target="libdb2_36.dylib" os="!windows"/>
<dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dylib" os="!windows" />
<dllmap dll="i:msvcrt" target="libc.dylib" os="!windows"/>
<dllmap dll="i:msvcrt.dll" target="libc.dylib" os="!windows"/>
<dllmap dll="sqlite" target="libsqlite.0.dylib" os="!windows"/>
<dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="!windows"/>
<dllmap dll="libX11" target="/usr/X11R6/lib/libX11.dylib" os="!windows" />
<dllmap dll="libcairo-2.dll" target="libcairo.2.dylib" os="!windows"/>
<dllmap dll="libcups" target="libcups.so.2" os="!windows"/>
<dllmap dll="i:kernel32.dll">
<dllentry dll="__Internal" name="CopyMemory" target="mono_win32_compat_CopyMemory"/>
<dllentry dll="__Internal" name="FillMemory" target="mono_win32_compat_FillMemory"/>
<dllentry dll="__Internal" name="MoveMemory" target="mono_win32_compat_MoveMemory"/>
<dllentry dll="__Internal" name="ZeroMemory" target="mono_win32_compat_ZeroMemory"/>
</dllmap>
<dllmap dll="gdiplus.dll" target="libgdiplus.dylib" />
<dllmap dll="gdiplus" target="libgdiplus.dylib" />
</configuration>

View file

@ -46,6 +46,9 @@ my ($diff_new_color) =
my $normal_color = $repo->get_color("", "reset"); my $normal_color = $repo->get_color("", "reset");
my $use_readkey = 0; my $use_readkey = 0;
my $use_termcap = 0;
my %term_escapes;
sub ReadMode; sub ReadMode;
sub ReadKey; sub ReadKey;
if ($repo->config_bool("interactive.singlekey")) { if ($repo->config_bool("interactive.singlekey")) {
@ -54,6 +57,14 @@ if ($repo->config_bool("interactive.singlekey")) {
Term::ReadKey->import; Term::ReadKey->import;
$use_readkey = 1; $use_readkey = 1;
}; };
eval {
require Term::Cap;
my $termcap = Term::Cap->Tgetent;
foreach (values %$termcap) {
$term_escapes{$_} = 1 if /^\e/;
}
$use_termcap = 1;
};
} }
sub colored { sub colored {
@ -706,7 +717,7 @@ sub add_untracked_cmd {
sub run_git_apply { sub run_git_apply {
my $cmd = shift; my $cmd = shift;
my $fh; my $fh;
open $fh, '| git ' . $cmd; open $fh, '| git ' . $cmd . " --recount --allow-overlap";
print $fh @_; print $fh @_;
return close $fh; return close $fh;
} }
@ -1051,7 +1062,7 @@ EOF
sub diff_applies { sub diff_applies {
my $fh; my $fh;
return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --recount --check', return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --check',
map { @{$_->{TEXT}} } @_); map { @{$_->{TEXT}} } @_);
} }
@ -1068,6 +1079,14 @@ sub prompt_single_character {
ReadMode 'cbreak'; ReadMode 'cbreak';
my $key = ReadKey 0; my $key = ReadKey 0;
ReadMode 'restore'; ReadMode 'restore';
if ($use_termcap and $key eq "\e") {
while (!defined $term_escapes{$key}) {
my $next = ReadKey 0.5;
last if (!defined $next);
$key .= $next;
}
$key =~ s/\e/^[/;
}
print "$key" if defined $key; print "$key" if defined $key;
print "\n"; print "\n";
return $key; return $key;
@ -1140,7 +1159,7 @@ EOF
sub apply_patch { sub apply_patch {
my $cmd = shift; my $cmd = shift;
my $ret = run_git_apply $cmd . ' --recount', @_; my $ret = run_git_apply $cmd, @_;
if (!$ret) { if (!$ret) {
print STDERR @_; print STDERR @_;
} }
@ -1149,17 +1168,17 @@ sub apply_patch {
sub apply_patch_for_checkout_commit { sub apply_patch_for_checkout_commit {
my $reverse = shift; my $reverse = shift;
my $applies_index = run_git_apply 'apply '.$reverse.' --cached --recount --check', @_; my $applies_index = run_git_apply 'apply '.$reverse.' --cached --check', @_;
my $applies_worktree = run_git_apply 'apply '.$reverse.' --recount --check', @_; my $applies_worktree = run_git_apply 'apply '.$reverse.' --check', @_;
if ($applies_worktree && $applies_index) { if ($applies_worktree && $applies_index) {
run_git_apply 'apply '.$reverse.' --cached --recount', @_; run_git_apply 'apply '.$reverse.' --cached', @_;
run_git_apply 'apply '.$reverse.' --recount', @_; run_git_apply 'apply '.$reverse, @_;
return 1; return 1;
} elsif (!$applies_index) { } elsif (!$applies_index) {
print colored $error_color, "The selected hunks do not apply to the index!\n"; print colored $error_color, "The selected hunks do not apply to the index!\n";
if (prompt_yesno "Apply them to the worktree anyway? ") { if (prompt_yesno "Apply them to the worktree anyway? ") {
return run_git_apply 'apply '.$reverse.' --recount', @_; return run_git_apply 'apply '.$reverse, @_;
} else { } else {
print colored $error_color, "Nothing was applied.\n"; print colored $error_color, "Nothing was applied.\n";
return 0; return 0;
@ -1367,14 +1386,13 @@ sub patch_update_file {
next; next;
} }
elsif ($line =~ /^q/i) { elsif ($line =~ /^q/i) {
while ($ix < $num) { for ($i = 0; $i < $num; $i++) {
if (!defined $hunk[$ix]{USE}) { if (!defined $hunk[$i]{USE}) {
$hunk[$ix]{USE} = 0; $hunk[$i]{USE} = 0;
} }
$ix++;
} }
$quit = 1; $quit = 1;
next; last;
} }
elsif ($line =~ m|^/(.*)|) { elsif ($line =~ m|^/(.*)|) {
my $regex = $1; my $regex = $1;

View file

@ -507,6 +507,8 @@ else
fi fi
fi fi
git update-index -q --refresh
case "$resolved" in case "$resolved" in
'') '')
case "$HAS_HEAD" in case "$HAS_HEAD" in

View file

@ -288,10 +288,12 @@ bisect_visualize() {
if test $# = 0 if test $# = 0
then then
case "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" &&
'') set git log ;; type gitk >/dev/null 2>&1; then
set*) set gitk ;; set gitk
esac else
set git log
fi
else else
case "$1" in case "$1" in
git*|tig) ;; git*|tig) ;;

View file

@ -2,7 +2,7 @@
if test "z$*" = zversion || if test "z$*" = zversion ||
test "z$*" = z--version test "z$*" = z--version
then then
echo 'git-gui version 0.13.0.8.g8f85' echo 'git-gui version 0.14.0-dirty'
else else
exec '/usr/local/git/share/git-gui/lib/Git Gui.app/Contents/MacOS/Wish' "$0" "$@" exec '/usr/local/git/share/git-gui/lib/Git Gui.app/Contents/MacOS/Wish' "$0" "$@"
fi fi

View file

@ -228,6 +228,31 @@ sub new {
return $self; return $self;
} }
sub find_password_entry {
my ($cvspass, @cvsroot) = @_;
my ($file, $delim) = @$cvspass;
my $pass;
local ($_);
if (open(my $fh, $file)) {
# :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z
CVSPASSFILE:
while (<$fh>) {
chomp;
s/^\/\d+\s+//;
my ($w, $p) = split($delim,$_,2);
for my $cvsroot (@cvsroot) {
if ($w eq $cvsroot) {
$pass = $p;
last CVSPASSFILE;
}
}
}
close($fh);
}
return $pass;
}
sub conn { sub conn {
my $self = shift; my $self = shift;
my $repo = $self->{'fullrep'}; my $repo = $self->{'fullrep'};
@ -260,19 +285,23 @@ sub conn {
if ($pass) { if ($pass) {
$pass = $self->_scramble($pass); $pass = $self->_scramble($pass);
} else { } else {
open(H,$ENV{'HOME'}."/.cvspass") and do { my @cvspass = ([$ENV{'HOME'}."/.cvspass", qr/\s/],
# :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z [$ENV{'HOME'}."/.cvs/cvspass", qr/=/]);
while (<H>) { my @loc = ();
chomp; foreach my $cvspass (@cvspass) {
s/^\/\d+\s+//; my $p = find_password_entry($cvspass, $rr, $rr2);
my ($w,$p) = split(/\s/,$_,2); if ($p) {
if ($w eq $rr or $w eq $rr2) { push @loc, $cvspass->[0];
$pass = $p; $pass = $p;
last;
} }
} }
};
$pass = "A" unless $pass; if (1 < @loc) {
die("Multiple cvs password files have ".
"entries for CVSROOT $opt_d: @loc");
} elsif (!$pass) {
$pass = "A";
}
} }
my ($s, $rep); my ($s, $rep);
@ -367,7 +396,9 @@ sub conn {
$self->{'socketo'}->write("valid-requests\n"); $self->{'socketo'}->write("valid-requests\n");
$self->{'socketo'}->flush(); $self->{'socketo'}->flush();
chomp(my $rep=$self->readline()); my $rep=$self->readline();
die "Failed to read from server" unless defined $rep;
chomp($rep);
if ($rep !~ s/^Valid-requests\s*//) { if ($rep !~ s/^Valid-requests\s*//) {
$rep="<unknown>" unless $rep; $rep="<unknown>" unless $rep;
die "Expected Valid-requests from server, but got: $rep\n"; die "Expected Valid-requests from server, but got: $rep\n";

View file

@ -27,7 +27,7 @@ use File::Path qw/rmtree/;
use File::Basename; use File::Basename;
use Getopt::Long qw(:config require_order no_ignore_case); use Getopt::Long qw(:config require_order no_ignore_case);
my $VERSION = '1.7.4'; my $VERSION = '1.7.6.1';
my $log = GITCVS::log->new(); my $log = GITCVS::log->new();
my $cfg; my $cfg;

View file

@ -363,7 +363,7 @@ while read commit parents; do
sed -e '1,/^$/d' <../commit | \ sed -e '1,/^$/d' <../commit | \
eval "$filter_msg" > ../message || eval "$filter_msg" > ../message ||
die "msg filter failed: $filter_msg" die "msg filter failed: $filter_msg"
/bin/sh -c "$filter_commit" "git commit-tree" \ workdir=$workdir /bin/sh -c "$filter_commit" "git commit-tree" \
$(git write-tree) $parentstr < ../message > ../map/$commit || $(git write-tree) $parentstr < ../message > ../map/$commit ||
die "could not write rewritten commit" die "could not write rewritten commit"
done <../revs done <../revs

View file

@ -2,7 +2,7 @@
if test "z$*" = zversion || if test "z$*" = zversion ||
test "z$*" = z--version test "z$*" = z--version
then then
echo 'git-gui version 0.13.0.8.g8f85' echo 'git-gui version 0.14.0-dirty'
else else
exec '/usr/local/git/share/git-gui/lib/Git Gui.app/Contents/MacOS/Wish' "$0" "$@" exec '/usr/local/git/share/git-gui/lib/Git Gui.app/Contents/MacOS/Wish' "$0" "$@"
fi fi

View file

@ -558,7 +558,9 @@ my \$app = builder {
# make it runnable as standalone app, # make it runnable as standalone app,
# like it would be run via 'plackup' utility # like it would be run via 'plackup' utility
if (__FILE__ eq \$0) { if (caller) {
return \$app;
} else {
require Plack::Runner; require Plack::Runner;
my \$runner = Plack::Runner->new(); my \$runner = Plack::Runner->new();

View file

@ -22,6 +22,11 @@ LONG_USAGE="Usage: git merge-one-file $USAGE
Blob ids and modes should be empty for missing files." Blob ids and modes should be empty for missing files."
SUBDIRECTORY_OK=Yes
. git-sh-setup
cd_to_toplevel
require_work_tree
if ! test "$#" -eq 7 if ! test "$#" -eq 7
then then
echo "$LONG_USAGE" echo "$LONG_USAGE"
@ -132,7 +137,7 @@ case "${1:-.}${2:-.}${3:-.}" in
# Create the working tree file, using "our tree" version from the # Create the working tree file, using "our tree" version from the
# index, and then store the result of the merge. # index, and then store the result of the merge.
git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1
rm -f -- "$orig" "$src1" "$src2" rm -f -- "$orig" "$src1" "$src2"
if [ "$6" != "$7" ]; then if [ "$6" != "$7" ]; then

View file

@ -21,6 +21,10 @@ is_symlink () {
test "$1" = 120000 test "$1" = 120000
} }
is_submodule () {
test "$1" = 160000
}
local_present () { local_present () {
test -n "$local_mode" test -n "$local_mode"
} }
@ -35,7 +39,8 @@ base_present () {
cleanup_temp_files () { cleanup_temp_files () {
if test "$1" = --save-backup ; then if test "$1" = --save-backup ; then
mv -- "$BACKUP" "$MERGED.orig" rm -rf -- "$MERGED.orig"
test -e "$BACKUP" && mv -- "$BACKUP" "$MERGED.orig"
rm -f -- "$LOCAL" "$REMOTE" "$BASE" rm -f -- "$LOCAL" "$REMOTE" "$BASE"
else else
rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP" rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP"
@ -52,11 +57,13 @@ describe_file () {
echo "deleted" echo "deleted"
elif is_symlink "$mode" ; then elif is_symlink "$mode" ; then
echo "a symbolic link -> '$(cat "$file")'" echo "a symbolic link -> '$(cat "$file")'"
elif is_submodule "$mode" ; then
echo "submodule commit $file"
else else
if base_present; then if base_present; then
echo "modified" echo "modified file"
else else
echo "created" echo "created file"
fi fi
fi fi
} }
@ -112,6 +119,67 @@ resolve_deleted_merge () {
done done
} }
resolve_submodule_merge () {
while true; do
printf "Use (l)ocal or (r)emote, or (a)bort? "
read ans
case "$ans" in
[lL]*)
if ! local_present; then
if test -n "$(git ls-tree HEAD -- "$MERGED")"; then
# Local isn't present, but it's a subdirectory
git ls-tree --full-name -r HEAD -- "$MERGED" | git update-index --index-info || exit $?
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
git update-index --force-remove "$MERGED"
cleanup_temp_files --save-backup
fi
elif is_submodule "$local_mode"; then
stage_submodule "$MERGED" "$local_sha1"
else
git checkout-index -f --stage=2 -- "$MERGED"
git add -- "$MERGED"
fi
return 0
;;
[rR]*)
if ! remote_present; then
if test -n "$(git ls-tree MERGE_HEAD -- "$MERGED")"; then
# Remote isn't present, but it's a subdirectory
git ls-tree --full-name -r MERGE_HEAD -- "$MERGED" | git update-index --index-info || exit $?
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
git update-index --force-remove "$MERGED"
fi
elif is_submodule "$remote_mode"; then
! is_submodule "$local_mode" && test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
stage_submodule "$MERGED" "$remote_sha1"
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
git checkout-index -f --stage=3 -- "$MERGED"
git add -- "$MERGED"
fi
cleanup_temp_files --save-backup
return 0
;;
[aA]*)
return 1
;;
esac
done
}
stage_submodule () {
path="$1"
submodule_sha1="$2"
mkdir -p "$path" || die "fatal: unable to create directory for module at $path"
# Find $path relative to work tree
work_tree_root=$(cd_to_toplevel && pwd)
work_rel_path=$(cd "$path" && GIT_WORK_TREE="${work_tree_root}" git rev-parse --show-prefix)
test -n "$work_rel_path" || die "fatal: unable to get path of module $path relative to work tree"
git update-index --add --replace --cacheinfo 160000 "$submodule_sha1" "${work_rel_path%/}" || die
}
checkout_staged_file () { checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ') tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
@ -139,13 +207,23 @@ merge_file () {
REMOTE="./$MERGED.REMOTE.$ext" REMOTE="./$MERGED.REMOTE.$ext"
BASE="./$MERGED.BASE.$ext" BASE="./$MERGED.BASE.$ext"
mv -- "$MERGED" "$BACKUP"
cp -- "$BACKUP" "$MERGED"
base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}') base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}') local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}') remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
if is_submodule "$local_mode" || is_submodule "$remote_mode"; then
echo "Submodule merge conflict for '$MERGED':"
local_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $2;}')
remote_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $2;}')
describe_file "$local_mode" "local" "$local_sha1"
describe_file "$remote_mode" "remote" "$remote_sha1"
resolve_submodule_merge
return
fi
mv -- "$MERGED" "$BACKUP"
cp -- "$BACKUP" "$MERGED"
base_present && checkout_staged_file 1 "$MERGED" "$BASE" base_present && checkout_staged_file 1 "$MERGED" "$BASE"
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL" local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE" remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE"
@ -269,7 +347,7 @@ rerere=false
files_to_merge() { files_to_merge() {
if test "$rerere" = true if test "$rerere" = true
then then
git rerere status git rerere remaining
else else
git ls-files -u | sed -e 's/^[^ ]* //' | sort -u git ls-files -u | sed -e 's/^[^ ]* //' | sort -u
fi fi

View file

@ -10,17 +10,20 @@ merge_mode() {
translate_merge_tool_path () { translate_merge_tool_path () {
case "$1" in case "$1" in
vimdiff|vimdiff2) araxis)
echo vim echo compare
;; ;;
gvimdiff|gvimdiff2) bc3)
echo gvim echo bcompare
;; ;;
emerge) emerge)
echo emacs echo emacs
;; ;;
araxis) gvimdiff|gvimdiff2)
echo compare echo gvim
;;
vimdiff|vimdiff2)
echo vim
;; ;;
*) *)
echo "$1" echo "$1"
@ -46,17 +49,16 @@ check_unchanged () {
valid_tool () { valid_tool () {
case "$1" in case "$1" in
kdiff3 | tkdiff | xxdiff | meld | opendiff | \ araxis | bc3 | diffuse | ecmerge | emerge | gvimdiff | gvimdiff2 | \
vimdiff | gvimdiff | vimdiff2 | gvimdiff2 | \ kdiff3 | meld | opendiff | p4merge | tkdiff | vimdiff | vimdiff2 | xxdiff)
emerge | ecmerge | diffuse | araxis | p4merge)
;; # happy ;; # happy
tortoisemerge) kompare)
if ! merge_mode; then if ! diff_mode; then
return 1 return 1
fi fi
;; ;;
kompare) tortoisemerge)
if ! diff_mode; then if ! merge_mode; then
return 1 return 1
fi fi
;; ;;
@ -89,66 +91,34 @@ run_merge_tool () {
status=0 status=0
case "$1" in case "$1" in
kdiff3) araxis)
if merge_mode; then
if $base_present; then
("$merge_tool_path" --auto \
--L1 "$MERGED (Base)" \
--L2 "$MERGED (Local)" \
--L3 "$MERGED (Remote)" \
-o "$MERGED" \
"$BASE" "$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
else
("$merge_tool_path" --auto \
--L1 "$MERGED (Local)" \
--L2 "$MERGED (Remote)" \
-o "$MERGED" \
"$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
fi
status=$?
else
("$merge_tool_path" --auto \
--L1 "$MERGED (A)" \
--L2 "$MERGED (B)" "$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
fi
;;
kompare)
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;
tkdiff)
if merge_mode; then
if $base_present; then
"$merge_tool_path" -a "$BASE" \
-o "$MERGED" "$LOCAL" "$REMOTE"
else
"$merge_tool_path" \
-o "$MERGED" "$LOCAL" "$REMOTE"
fi
status=$?
else
"$merge_tool_path" "$LOCAL" "$REMOTE"
fi
;;
p4merge)
if merge_mode; then if merge_mode; then
touch "$BACKUP" touch "$BACKUP"
if $base_present; then if $base_present; then
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED" "$merge_tool_path" -wait -merge -3 -a1 \
"$BASE" "$LOCAL" "$REMOTE" "$MERGED" \
>/dev/null 2>&1
else else
"$merge_tool_path" "$LOCAL" "$LOCAL" "$REMOTE" "$MERGED" "$merge_tool_path" -wait -2 \
"$LOCAL" "$REMOTE" "$MERGED" \
>/dev/null 2>&1
fi fi
check_unchanged check_unchanged
else else
"$merge_tool_path" "$LOCAL" "$REMOTE" "$merge_tool_path" -wait -2 "$LOCAL" "$REMOTE" \
>/dev/null 2>&1
fi fi
;; ;;
meld) bc3)
if merge_mode; then if merge_mode; then
touch "$BACKUP" touch "$BACKUP"
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" if $base_present; then
"$merge_tool_path" "$LOCAL" "$REMOTE" "$BASE" \
-mergeoutput="$MERGED"
else
"$merge_tool_path" "$LOCAL" "$REMOTE" \
-mergeoutput="$MERGED"
fi
check_unchanged check_unchanged
else else
"$merge_tool_path" "$LOCAL" "$REMOTE" "$merge_tool_path" "$LOCAL" "$REMOTE"
@ -170,75 +140,6 @@ run_merge_tool () {
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
fi fi
;; ;;
vimdiff|gvimdiff)
if merge_mode; then
touch "$BACKUP"
if $base_present; then
"$merge_tool_path" -f -d -c "wincmd J" \
"$MERGED" "$LOCAL" "$BASE" "$REMOTE"
else
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$MERGED" "$REMOTE"
fi
check_unchanged
else
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$REMOTE"
fi
;;
vimdiff2|gvimdiff2)
if merge_mode; then
touch "$BACKUP"
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$MERGED" "$REMOTE"
check_unchanged
else
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$REMOTE"
fi
;;
xxdiff)
if merge_mode; then
touch "$BACKUP"
if $base_present; then
"$merge_tool_path" -X --show-merged-pane \
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
-R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
--merged-file "$MERGED" \
"$LOCAL" "$BASE" "$REMOTE"
else
"$merge_tool_path" -X $extra \
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
-R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
--merged-file "$MERGED" \
"$LOCAL" "$REMOTE"
fi
check_unchanged
else
"$merge_tool_path" \
-R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
"$LOCAL" "$REMOTE"
fi
;;
opendiff)
if merge_mode; then
touch "$BACKUP"
if $base_present; then
"$merge_tool_path" "$LOCAL" "$REMOTE" \
-ancestor "$BASE" \
-merge "$MERGED" | cat
else
"$merge_tool_path" "$LOCAL" "$REMOTE" \
-merge "$MERGED" | cat
fi
check_unchanged
else
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
fi
;;
ecmerge) ecmerge)
if merge_mode; then if merge_mode; then
touch "$BACKUP" touch "$BACKUP"
@ -274,6 +175,111 @@ run_merge_tool () {
"$LOCAL" "$REMOTE" "$LOCAL" "$REMOTE"
fi fi
;; ;;
gvimdiff|vimdiff)
if merge_mode; then
touch "$BACKUP"
if $base_present; then
"$merge_tool_path" -f -d -c "wincmd J" \
"$MERGED" "$LOCAL" "$BASE" "$REMOTE"
else
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$MERGED" "$REMOTE"
fi
check_unchanged
else
"$merge_tool_path" -R -f -d -c "wincmd l" \
"$LOCAL" "$REMOTE"
fi
;;
gvimdiff2|vimdiff2)
if merge_mode; then
touch "$BACKUP"
"$merge_tool_path" -f -d -c "wincmd l" \
"$LOCAL" "$MERGED" "$REMOTE"
check_unchanged
else
"$merge_tool_path" -R -f -d -c "wincmd l" \
"$LOCAL" "$REMOTE"
fi
;;
kdiff3)
if merge_mode; then
if $base_present; then
("$merge_tool_path" --auto \
--L1 "$MERGED (Base)" \
--L2 "$MERGED (Local)" \
--L3 "$MERGED (Remote)" \
-o "$MERGED" \
"$BASE" "$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
else
("$merge_tool_path" --auto \
--L1 "$MERGED (Local)" \
--L2 "$MERGED (Remote)" \
-o "$MERGED" \
"$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
fi
status=$?
else
("$merge_tool_path" --auto \
--L1 "$MERGED (A)" \
--L2 "$MERGED (B)" "$LOCAL" "$REMOTE" \
> /dev/null 2>&1)
fi
;;
kompare)
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;
meld)
if merge_mode; then
touch "$BACKUP"
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
check_unchanged
else
"$merge_tool_path" "$LOCAL" "$REMOTE"
fi
;;
opendiff)
if merge_mode; then
touch "$BACKUP"
if $base_present; then
"$merge_tool_path" "$LOCAL" "$REMOTE" \
-ancestor "$BASE" \
-merge "$MERGED" | cat
else
"$merge_tool_path" "$LOCAL" "$REMOTE" \
-merge "$MERGED" | cat
fi
check_unchanged
else
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
fi
;;
p4merge)
if merge_mode; then
touch "$BACKUP"
$base_present || >"$BASE"
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
check_unchanged
else
"$merge_tool_path" "$LOCAL" "$REMOTE"
fi
;;
tkdiff)
if merge_mode; then
if $base_present; then
"$merge_tool_path" -a "$BASE" \
-o "$MERGED" "$LOCAL" "$REMOTE"
else
"$merge_tool_path" \
-o "$MERGED" "$LOCAL" "$REMOTE"
fi
status=$?
else
"$merge_tool_path" "$LOCAL" "$REMOTE"
fi
;;
tortoisemerge) tortoisemerge)
if $base_present; then if $base_present; then
touch "$BACKUP" touch "$BACKUP"
@ -286,22 +292,30 @@ run_merge_tool () {
status=1 status=1
fi fi
;; ;;
araxis) xxdiff)
if merge_mode; then if merge_mode; then
touch "$BACKUP" touch "$BACKUP"
if $base_present; then if $base_present; then
"$merge_tool_path" -wait -merge -3 -a1 \ "$merge_tool_path" -X --show-merged-pane \
"$BASE" "$LOCAL" "$REMOTE" "$MERGED" \ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
>/dev/null 2>&1 -R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
--merged-file "$MERGED" \
"$LOCAL" "$BASE" "$REMOTE"
else else
"$merge_tool_path" -wait -2 \ "$merge_tool_path" -X $extra \
"$LOCAL" "$REMOTE" "$MERGED" \ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
>/dev/null 2>&1 -R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
--merged-file "$MERGED" \
"$LOCAL" "$REMOTE"
fi fi
check_unchanged check_unchanged
else else
"$merge_tool_path" -wait -2 "$LOCAL" "$REMOTE" \ "$merge_tool_path" \
>/dev/null 2>&1 -R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
"$LOCAL" "$REMOTE"
fi fi
;; ;;
*) *)
@ -343,7 +357,7 @@ guess_merge_tool () {
else else
tools="opendiff kdiff3 tkdiff xxdiff meld $tools" tools="opendiff kdiff3 tkdiff xxdiff meld $tools"
fi fi
tools="$tools gvimdiff diffuse ecmerge p4merge araxis" tools="$tools gvimdiff diffuse ecmerge p4merge araxis bc3"
fi fi
case "${VISUAL:-$EDITOR}" in case "${VISUAL:-$EDITOR}" in
*vim*) *vim*)

View file

@ -4,58 +4,9 @@
# this would fail in that case and would issue an error message. # this would fail in that case and would issue an error message.
GIT_DIR=$(git rev-parse -q --git-dir) || :; GIT_DIR=$(git rev-parse -q --git-dir) || :;
get_data_source () {
case "$1" in
*/*)
echo ''
;;
.)
echo self
;;
*)
if test "$(git config --get "remote.$1.url")"
then
echo config
elif test -f "$GIT_DIR/remotes/$1"
then
echo remotes
elif test -f "$GIT_DIR/branches/$1"
then
echo branches
else
echo ''
fi ;;
esac
}
get_remote_url () {
data_source=$(get_data_source "$1")
case "$data_source" in
'')
echo "$1"
;;
self)
echo "$1"
;;
config)
git config --get "remote.$1.url"
;;
remotes)
sed -ne '/^URL: */{
s///p
q
}' "$GIT_DIR/remotes/$1"
;;
branches)
sed -e 's/#.*//' "$GIT_DIR/branches/$1"
;;
*)
die "internal error: get-remote-url $1" ;;
esac
}
get_default_remote () { get_default_remote () {
curr_branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||') curr_branch=$(git symbolic-ref -q HEAD)
curr_branch="${curr_branch#refs/heads/}"
origin=$(git config --get "branch.$curr_branch.remote") origin=$(git config --get "branch.$curr_branch.remote")
echo ${origin:-origin} echo ${origin:-origin}
} }
@ -99,3 +50,41 @@ get_remote_merge_branch () {
esac esac
esac esac
} }
error_on_missing_default_upstream () {
cmd="$1"
op_type="$2"
op_prep="$3"
example="$4"
branch_name=$(git symbolic-ref -q HEAD)
if test -z "$branch_name"
then
echo "You are not currently on a branch, so I cannot use any
'branch.<branchname>.merge' in your configuration file.
Please specify which branch you want to $op_type $op_prep on the command
line and try again (e.g. '$example').
See git-${cmd}(1) for details."
else
echo "You asked me to $cmd without telling me which branch you
want to $op_type $op_prep, and 'branch.${branch_name#refs/heads/}.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. '$example').
See git-${cmd}(1) for details.
If you often $op_type $op_prep the same branch, you may want to
use something like the following in your configuration file:
[branch \"${branch_name#refs/heads/}\"]
remote = <nickname>
merge = <remote-ref>"
test rebase = "$op_type" &&
echo " rebase = true"
echo "
[remote \"<nickname>\"]
url = <url>
fetch = <refspec>
See git-config(1) for details."
fi
exit 1
}

View file

@ -9,7 +9,7 @@ LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEA
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC= OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
set_reflog_action "pull $*" set_reflog_action "pull${1+ $*}"
require_work_tree require_work_tree
cd_to_toplevel cd_to_toplevel
@ -53,6 +53,8 @@ do
verbosity="$verbosity -v" ;; verbosity="$verbosity -v" ;;
--progress) --progress)
progress=--progress ;; progress=--progress ;;
--no-progress)
progress=--no-progress ;;
-n|--no-stat|--no-summary) -n|--no-stat|--no-summary)
diffstat=--no-stat ;; diffstat=--no-stat ;;
--stat|--summary) --stat|--summary)
@ -108,13 +110,16 @@ do
--recurse-submodules) --recurse-submodules)
recurse_submodules=--recurse-submodules recurse_submodules=--recurse-submodules
;; ;;
--recurse-submodules=*)
recurse_submodules="$1"
;;
--no-recurse-submodules) --no-recurse-submodules)
recurse_submodules=--no-recurse-submodules recurse_submodules=--no-recurse-submodules
;; ;;
--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
dry_run=--dry-run dry_run=--dry-run
;; ;;
-h|--h|--he|--hel|--help) -h|--h|--he|--hel|--help|--help-|--help-a|--help-al|--help-all)
usage usage
;; ;;
*) *)
@ -163,34 +168,10 @@ error_on_no_merge_candidates () {
echo "You asked to pull from the remote '$1', but did not specify" echo "You asked to pull from the remote '$1', but did not specify"
echo "a branch. Because this is not the default configured remote" echo "a branch. Because this is not the default configured remote"
echo "for your current branch, you must specify a branch on the command line." echo "for your current branch, you must specify a branch on the command line."
elif [ -z "$curr_branch" ]; then elif [ -z "$curr_branch" -o -z "$upstream" ]; then
echo "You are not currently on a branch, so I cannot use any" . git-parse-remote
echo "'branch.<branchname>.merge' in your configuration file." error_on_missing_default_upstream "pull" $op_type $op_prep \
echo "Please specify which remote branch you want to use on the command" "git pull <repository> <refspec>"
echo "line and try again (e.g. 'git pull <repository> <refspec>')."
echo "See git-pull(1) for details."
elif [ -z "$upstream" ]; then
echo "You asked me to pull without telling me which branch you"
echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
echo "your configuration file does not tell me, either. Please"
echo "specify which branch you want to use on the command line and"
echo "try again (e.g. 'git pull <repository> <refspec>')."
echo "See git-pull(1) for details."
echo
echo "If you often $op_type $op_prep the same branch, you may want to"
echo "use something like the following in your configuration file:"
echo
echo " [branch \"${curr_branch}\"]"
echo " remote = <nickname>"
echo " merge = <remote-ref>"
test rebase = "$op_type" &&
echo " rebase = true"
echo
echo " [remote \"<nickname>\"]"
echo " url = <url>"
echo " fetch = <refspec>"
echo
echo "See git-config(1) for details."
else else
echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'" echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
echo "from the remote, but no such ref was fetched." echo "from the remote, but no such ref was fetched."
@ -272,7 +253,7 @@ esac
if test -z "$orig_head" if test -z "$orig_head"
then then
git update-ref -m "initial pull" HEAD $merge_head "$curr_head" && git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
git read-tree --reset -u HEAD || exit 1 git read-tree -m -u HEAD || exit 1
exit exit
fi fi
@ -293,8 +274,8 @@ true)
;; ;;
*) *)
eval="git-merge $diffstat $no_commit $squash $no_ff $ff_only" eval="git-merge $diffstat $no_commit $squash $no_ff $ff_only"
eval="$eval $log_arg $strategy_args $merge_args" eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress"
eval="$eval \"\$merge_name\" HEAD $merge_head $verbosity" eval="$eval \"\$merge_name\" HEAD $merge_head"
;; ;;
esac esac
eval "exec $eval" eval "exec $eval"

View file

@ -3,7 +3,7 @@
# Copyright (c) 2005 Junio C Hamano. # Copyright (c) 2005 Junio C Hamano.
# #
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] (<upstream>|--root) [<branch>] [--quiet | -q]' USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
LONG_USAGE='git-rebase replaces <branch> with a new branch of the LONG_USAGE='git-rebase replaces <branch> with a new branch of the
same name. When the --onto option is provided the new branch starts same name. When the --onto option is provided the new branch starts
out with a HEAD equal to <newbase>, otherwise it is equal to <upstream> out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@ -13,7 +13,7 @@ It then attempts to create a new commit for each commit from the original
It is possible that a merge failure will prevent this process from being It is possible that a merge failure will prevent this process from being
completely automatic. You will have to resolve any such merge failure completely automatic. You will have to resolve any such merge failure
and run git rebase --continue. Another option is to bypass the commit and run git rebase --continue. Another option is to bypass the commit
that caused the merge failure with git rebase --skip. To restore the that caused the merge failure with git rebase --skip. To check out the
original <branch> and remove the .git/rebase-apply working files, use the original <branch> and remove the .git/rebase-apply working files, use the
command git rebase --abort instead. command git rebase --abort instead.
@ -28,7 +28,39 @@ Example: git-rebase master~1 topic
' '
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC= OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
git rebase [-i] [options] --onto <newbase> --root [<branch>]
git-rebase [-i] --continue | --abort | --skip
--
Available options are
v,verbose! display a diffstat of what changed upstream
q,quiet! be quiet. implies --no-stat
onto=! rebase onto given branch instead of upstream
p,preserve-merges! try to recreate merges instead of ignoring them
s,strategy=! use the given merge strategy
no-ff! cherry-pick all commits, even if unchanged
m,merge! use merging strategies to rebase
i,interactive! let the user edit the list of commits to rebase
f,force-rebase! force rebase even if branch is up to date
X,strategy-option=! pass the argument through to the merge strategy
stat! display a diffstat of what changed upstream
n,no-stat! do not show diffstat of what changed upstream
verify allow pre-rebase hook to run
rerere-autoupdate allow rerere to update index with resolved conflicts
root! rebase all reachable commits up to the root(s)
autosquash move commits that begin with squash!/fixup! under -i
committer-date-is-author-date! passed to 'git am'
ignore-date! passed to 'git am'
whitespace=! passed to 'git apply'
ignore-whitespace! passed to 'git apply'
C=! passed to 'git apply'
Actions:
continue! continue
abort! abort and check out the original branch
skip! skip current patch and continue
"
. git-sh-setup . git-sh-setup
set_reflog_action rebase set_reflog_action rebase
require_work_tree require_work_tree
@ -36,18 +68,18 @@ cd_to_toplevel
LF=' LF='
' '
OK_TO_SKIP_PRE_REBASE= ok_to_skip_pre_rebase=
RESOLVEMSG=" resolvemsg="
When you have resolved this problem run \"git rebase --continue\". When you have resolved this problem run \"git rebase --continue\".
If you would prefer to skip this patch, instead run \"git rebase --skip\". If you would prefer to skip this patch, instead run \"git rebase --skip\".
To restore the original branch and stop rebasing run \"git rebase --abort\". To check out the original branch and stop rebasing run \"git rebase --abort\".
" "
unset newbase unset onto
strategy=recursive strategy=
strategy_opts= strategy_opts=
do_merge= do_merge=
dotest="$GIT_DIR"/rebase-merge merge_dir="$GIT_DIR"/rebase-merge
prec=4 apply_dir="$GIT_DIR"/rebase-apply
verbose= verbose=
diffstat= diffstat=
test "$(git config --bool rebase.stat)" = true && diffstat=t test "$(git config --bool rebase.stat)" = true && diffstat=t
@ -55,139 +87,90 @@ git_am_opt=
rebase_root= rebase_root=
force_rebase= force_rebase=
allow_rerere_autoupdate= allow_rerere_autoupdate=
# Non-empty if a rebase was in progress when 'git rebase' was invoked
in_progress=
# One of {am, merge, interactive}
type=
# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
state_dir=
# One of {'', continue, skip, abort}, as parsed from command line
action=
preserve_merges=
autosquash=
test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
continue_merge () { read_basic_state () {
test -n "$prev_head" || die "prev_head must be defined" head_name=$(cat "$state_dir"/head-name) &&
test -d "$dotest" || die "$dotest directory does not exist" onto=$(cat "$state_dir"/onto) &&
# We always write to orig-head, but interactive rebase used to write to
unmerged=$(git ls-files -u) # head. Fall back to reading from head to cover for the case that the
if test -n "$unmerged" # user upgraded git with an ongoing interactive rebase.
if test -f "$state_dir"/orig-head
then then
echo "You still have unmerged paths in your index" orig_head=$(cat "$state_dir"/orig-head)
echo "did you forget to use git add?"
die "$RESOLVEMSG"
fi
cmt=`cat "$dotest/current"`
if ! git diff-index --quiet --ignore-submodules HEAD --
then
if ! git commit --no-verify -C "$cmt"
then
echo "Commit failed, please do not call \"git commit\""
echo "directly, but instead do one of the following: "
die "$RESOLVEMSG"
fi
if test -z "$GIT_QUIET"
then
printf "Committed: %0${prec}d " $msgnum
fi
echo "$cmt $(git rev-parse HEAD^0)" >> "$dotest/rewritten"
else else
if test -z "$GIT_QUIET" orig_head=$(cat "$state_dir"/head)
then fi &&
printf "Already applied: %0${prec}d " $msgnum GIT_QUIET=$(cat "$state_dir"/quiet) &&
fi test -f "$state_dir"/verbose && verbose=t
fi test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
test -z "$GIT_QUIET" && test -f "$state_dir"/strategy_opts &&
GIT_PAGER='' git log --format=%s -1 "$cmt" strategy_opts="$(cat "$state_dir"/strategy_opts)"
test -f "$state_dir"/allow_rerere_autoupdate &&
prev_head=`git rev-parse HEAD^0` allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
# save the resulting commit so we can read-tree on it later
echo "$prev_head" > "$dotest/prev_head"
# onto the next patch:
msgnum=$(($msgnum + 1))
echo "$msgnum" >"$dotest/msgnum"
} }
call_merge () { write_basic_state () {
cmt="$(cat "$dotest/cmt.$1")" echo "$head_name" > "$state_dir"/head-name &&
echo "$cmt" > "$dotest/current" echo "$onto" > "$state_dir"/onto &&
hd=$(git rev-parse --verify HEAD) echo "$orig_head" > "$state_dir"/orig-head &&
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD) echo "$GIT_QUIET" > "$state_dir"/quiet &&
msgnum=$(cat "$dotest/msgnum") test t = "$verbose" && : > "$state_dir"/verbose
end=$(cat "$dotest/end") test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"' test -n "$strategy_opts" && echo "$strategy_opts" > \
eval GITHEAD_$hd='$(cat "$dotest/onto_name")' "$state_dir"/strategy_opts
export GITHEAD_$cmt GITHEAD_$hd test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
if test -n "$GIT_QUIET" "$state_dir"/allow_rerere_autoupdate
then }
GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
fi output () {
eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"' case "$verbose" in
rv=$? '')
case "$rv" in output=$("$@" 2>&1 )
0) status=$?
unset GITHEAD_$cmt GITHEAD_$hd test $status != 0 && printf "%s\n" "$output"
return return $status
;;
1)
git rerere $allow_rerere_autoupdate
die "$RESOLVEMSG"
;;
2)
echo "Strategy: $rv $strategy failed, try another" 1>&2
die "$RESOLVEMSG"
;; ;;
*) *)
die "Unknown exit code ($rv) from command:" \ "$@"
"git-merge-$strategy $cmt^ -- HEAD $cmt"
;; ;;
esac esac
} }
move_to_original_branch () { move_to_original_branch () {
test -z "$head_name" &&
head_name="$(cat "$dotest"/head-name)" &&
onto="$(cat "$dotest"/onto)" &&
orig_head="$(cat "$dotest"/orig-head)"
case "$head_name" in case "$head_name" in
refs/*) refs/*)
message="rebase finished: $head_name onto $onto" message="rebase finished: $head_name onto $onto"
git update-ref -m "$message" \ git update-ref -m "$message" \
$head_name $(git rev-parse HEAD) $orig_head && $head_name $(git rev-parse HEAD) $orig_head &&
git symbolic-ref HEAD $head_name || git symbolic-ref \
-m "rebase finished: returning to $head_name" \
HEAD $head_name ||
die "Could not move back to $head_name" die "Could not move back to $head_name"
;; ;;
esac esac
} }
finish_rb_merge () { run_specific_rebase () {
move_to_original_branch
git notes copy --for-rewrite=rebase < "$dotest"/rewritten
if test -x "$GIT_DIR"/hooks/post-rewrite &&
test -s "$dotest"/rewritten; then
"$GIT_DIR"/hooks/post-rewrite rebase < "$dotest"/rewritten
fi
rm -r "$dotest"
say All done.
}
is_interactive () {
while test $# != 0
do
case "$1" in
-i|--interactive)
interactive_rebase=explicit
break
;;
-p|--preserve-merges)
interactive_rebase=implied
;;
esac
shift
done
if [ "$interactive_rebase" = implied ]; then if [ "$interactive_rebase" = implied ]; then
GIT_EDITOR=: GIT_EDITOR=:
export GIT_EDITOR export GIT_EDITOR
fi fi
. git-rebase--$type
test -n "$interactive_rebase" || test -f "$dotest"/interactive
} }
run_pre_rebase_hook () { run_pre_rebase_hook () {
if test -z "$OK_TO_SKIP_PRE_REBASE" && if test -z "$ok_to_skip_pre_rebase" &&
test -x "$GIT_DIR/hooks/pre-rebase" test -x "$GIT_DIR/hooks/pre-rebase"
then then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
@ -195,163 +178,94 @@ run_pre_rebase_hook () {
fi fi
} }
test -f "$GIT_DIR"/rebase-apply/applying && test -f "$apply_dir"/applying &&
die 'It looks like git-am is in progress. Cannot rebase.' die 'It looks like git-am is in progress. Cannot rebase.'
is_interactive "$@" && exec git-rebase--interactive "$@" if test -d "$apply_dir"
then
type=am
state_dir="$apply_dir"
elif test -d "$merge_dir"
then
if test -f "$merge_dir"/interactive
then
type=interactive
interactive_rebase=explicit
else
type=merge
fi
state_dir="$merge_dir"
fi
test -n "$type" && in_progress=t
total_argc=$#
while test $# != 0 while test $# != 0
do do
case "$1" in case "$1" in
--no-verify) --no-verify)
OK_TO_SKIP_PRE_REBASE=yes ok_to_skip_pre_rebase=yes
;; ;;
--verify) --verify)
OK_TO_SKIP_PRE_REBASE= ok_to_skip_pre_rebase=
;; ;;
--continue) --continue|--skip|--abort)
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || test $total_argc -eq 2 || usage
die "No rebase in progress?" action=${1##--}
git update-index --ignore-submodules --refresh &&
git diff-files --quiet --ignore-submodules || {
echo "You must edit all merge conflicts and then"
echo "mark them as resolved using git add"
exit 1
}
if test -d "$dotest"
then
prev_head=$(cat "$dotest/prev_head")
end=$(cat "$dotest/end")
msgnum=$(cat "$dotest/msgnum")
onto=$(cat "$dotest/onto")
GIT_QUIET=$(cat "$dotest/quiet")
continue_merge
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge
exit
fi
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
exit
;;
--skip)
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
die "No rebase in progress?"
git reset --hard HEAD || exit $?
if test -d "$dotest"
then
git rerere clear
prev_head=$(cat "$dotest/prev_head")
end=$(cat "$dotest/end")
msgnum=$(cat "$dotest/msgnum")
msgnum=$(($msgnum + 1))
onto=$(cat "$dotest/onto")
GIT_QUIET=$(cat "$dotest/quiet")
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge
exit
fi
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
exit
;;
--abort)
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
die "No rebase in progress?"
git rerere clear
test -d "$dotest" || dotest="$GIT_DIR"/rebase-apply
head_name="$(cat "$dotest"/head-name)" &&
case "$head_name" in
refs/*)
git symbolic-ref HEAD $head_name ||
die "Could not move back to $head_name"
;;
esac
git reset --hard $(cat "$dotest/orig-head")
rm -r "$dotest"
exit
;; ;;
--onto) --onto)
test 2 -le "$#" || usage test 2 -le "$#" || usage
newbase="$2" onto="$2"
shift shift
;; ;;
-M|-m|--m|--me|--mer|--merg|--merge) -i)
interactive_rebase=explicit
;;
-p)
preserve_merges=t
test -z "$interactive_rebase" && interactive_rebase=implied
;;
--autosquash)
autosquash=t
;;
--no-autosquash)
autosquash=
;;
-M|-m)
do_merge=t do_merge=t
;; ;;
-X*|--strategy-option*) -X)
case "$#,$1" in shift
1,-X|1,--strategy-option) strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
usage ;; do_merge=t
*,-X|*,--strategy-option) test -z "$strategy" && strategy=recursive
newopt="$2" ;;
shift ;; -s)
*,--strategy-option=*) shift
newopt="$(expr " $1" : ' --strategy-option=\(.*\)')" ;; strategy="$1"
*,-X*)
newopt="$(expr " $1" : ' -X\(.*\)')" ;;
1,*)
usage ;;
esac
strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$newopt")"
do_merge=t do_merge=t
;; ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ -n)
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
case "$#,$1" in
*,*=*)
strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
strategy="$2"
shift ;;
esac
do_merge=t
;;
-n|--no-stat)
diffstat= diffstat=
;; ;;
--stat) --stat)
diffstat=t diffstat=t
;; ;;
-v|--verbose) -v)
verbose=t verbose=t
diffstat=t diffstat=t
GIT_QUIET= GIT_QUIET=
;; ;;
-q|--quiet) -q)
GIT_QUIET=t GIT_QUIET=t
git_am_opt="$git_am_opt -q" git_am_opt="$git_am_opt -q"
verbose= verbose=
diffstat= diffstat=
;; ;;
--whitespace=*) --whitespace)
git_am_opt="$git_am_opt $1" shift
git_am_opt="$git_am_opt --whitespace=$1"
case "$1" in case "$1" in
--whitespace=fix|--whitespace=strip) fix|strip)
force_rebase=t force_rebase=t
;; ;;
esac esac
@ -363,22 +277,21 @@ do
git_am_opt="$git_am_opt $1" git_am_opt="$git_am_opt $1"
force_rebase=t force_rebase=t
;; ;;
-C*) -C)
git_am_opt="$git_am_opt $1" shift
git_am_opt="$git_am_opt -C$1"
;; ;;
--root) --root)
rebase_root=t rebase_root=t
;; ;;
-f|--f|--fo|--for|--forc|--force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase|--no-ff) -f|--no-ff)
force_rebase=t force_rebase=t
;; ;;
--rerere-autoupdate|--no-rerere-autoupdate) --rerere-autoupdate|--no-rerere-autoupdate)
allow_rerere_autoupdate="$1" allow_rerere_autoupdate="$1"
;; ;;
-*) --)
usage shift
;;
*)
break break
;; ;;
esac esac
@ -386,58 +299,106 @@ do
done done
test $# -gt 2 && usage test $# -gt 2 && usage
if test $# -eq 0 && test -z "$rebase_root" if test -n "$action"
then then
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || usage test -z "$in_progress" && die "No rebase in progress?"
test -d "$dotest" -o -f "$GIT_DIR"/rebase-apply/rebasing && # Only interactive rebase uses detailed reflog messages
die 'A rebase is in progress, try --continue, --skip or --abort.' if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
then
GIT_REFLOG_ACTION="rebase -i ($action)"
export GIT_REFLOG_ACTION
fi
fi fi
# Make sure we do not have $GIT_DIR/rebase-apply case "$action" in
if test -z "$do_merge" continue)
# Sanity check
git rev-parse --verify HEAD >/dev/null ||
die "Cannot read HEAD"
git update-index --ignore-submodules --refresh &&
git diff-files --quiet --ignore-submodules || {
echo "You must edit all merge conflicts and then"
echo "mark them as resolved using git add"
exit 1
}
read_basic_state
run_specific_rebase
;;
skip)
output git reset --hard HEAD || exit $?
read_basic_state
run_specific_rebase
;;
abort)
git rerere clear
read_basic_state
case "$head_name" in
refs/*)
git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
die "Could not move back to $head_name"
;;
esac
output git reset --hard $orig_head
rm -r "$state_dir"
exit
;;
esac
# Make sure no rebase is in progress
if test -n "$in_progress"
then then
if mkdir "$GIT_DIR"/rebase-apply 2>/dev/null die '
then It seems that there is already a '"${state_dir##*/}"' directory, and
rmdir "$GIT_DIR"/rebase-apply I wonder if you are in the middle of another rebase. If that is the
else case, please try
echo >&2 ' git rebase (--continue | --abort | --skip)
It seems that I cannot create a rebase-apply directory, and If that is not the case, please
I wonder if you are in the middle of patch application or another rm -fr '"$state_dir"'
rebase. If that is not the case, please
rm -fr '"$GIT_DIR"'/rebase-apply
and run me again. I am stopping in case you still have something and run me again. I am stopping in case you still have something
valuable there.' valuable there.'
exit 1
fi
else
if test -d "$dotest"
then
die "previous rebase directory $dotest still exists." \
'Try git rebase (--continue | --abort | --skip)'
fi
fi fi
require_clean_work_tree "rebase" "Please commit or stash them." if test -n "$interactive_rebase"
then
type=interactive
state_dir="$merge_dir"
elif test -n "$do_merge"
then
type=merge
state_dir="$merge_dir"
else
type=am
state_dir="$apply_dir"
fi
if test -z "$rebase_root" if test -z "$rebase_root"
then then
# The upstream head must be given. Make sure it is valid. case "$#" in
upstream_name="$1" 0)
if ! upstream_name=$(git rev-parse --symbolic-full-name \
--verify -q @{upstream} 2>/dev/null)
then
. git-parse-remote
error_on_missing_default_upstream "rebase" "rebase" \
"against" "git rebase <upstream branch>"
fi
;;
*) upstream_name="$1"
shift shift
;;
esac
upstream=`git rev-parse --verify "${upstream_name}^0"` || upstream=`git rev-parse --verify "${upstream_name}^0"` ||
die "invalid upstream $upstream_name" die "invalid upstream $upstream_name"
unset root_flag
upstream_arg="$upstream_name" upstream_arg="$upstream_name"
else else
test -z "$newbase" && die "--root must be used with --onto" test -z "$onto" && die "You must specify --onto when using --root"
unset upstream_name unset upstream_name
unset upstream unset upstream
root_flag="--root" upstream_arg=--root
upstream_arg="$root_flag"
fi fi
# Make sure the branch to rebase onto is valid. # Make sure the branch to rebase onto is valid.
onto_name=${newbase-"$upstream_name"} onto_name=${onto-"$upstream_name"}
case "$onto_name" in case "$onto_name" in
*...*) *...*)
if left=${onto_name%...*} right=${onto_name#*...} && if left=${onto_name%...*} right=${onto_name#*...} &&
@ -456,13 +417,11 @@ case "$onto_name" in
fi fi
;; ;;
*) *)
onto=$(git rev-parse --verify "${onto_name}^0") || exit onto=$(git rev-parse --verify "${onto_name}^0") ||
die "Does not point to a valid commit: $1"
;; ;;
esac esac
# If a hook exists, give it a chance to interrupt
run_pre_rebase_hook "$upstream_arg" "$@"
# If the branch to rebase is given, that is the branch we will rebase # If the branch to rebase is given, that is the branch we will rebase
# $branch_name -- branch being rebased, or HEAD (already detached) # $branch_name -- branch being rebased, or HEAD (already detached)
# $orig_head -- commit object name of tip of the branch before rebasing # $orig_head -- commit object name of tip of the branch before rebasing
@ -475,10 +434,10 @@ case "$#" in
switch_to="$1" switch_to="$1"
if git show-ref --verify --quiet -- "refs/heads/$1" && if git show-ref --verify --quiet -- "refs/heads/$1" &&
branch=$(git rev-parse -q --verify "refs/heads/$1") orig_head=$(git rev-parse -q --verify "refs/heads/$1")
then then
head_name="refs/heads/$1" head_name="refs/heads/$1"
elif branch=$(git rev-parse -q --verify "$1") elif orig_head=$(git rev-parse -q --verify "$1")
then then
head_name="detached HEAD" head_name="detached HEAD"
else else
@ -496,20 +455,23 @@ case "$#" in
head_name="detached HEAD" head_name="detached HEAD"
branch_name=HEAD ;# detached branch_name=HEAD ;# detached
fi fi
branch=$(git rev-parse --verify "${branch_name}^0") || exit orig_head=$(git rev-parse --verify "${branch_name}^0") || exit
;; ;;
esac esac
orig_head=$branch
# Now we are rebasing commits $upstream..$branch (or with --root, require_clean_work_tree "rebase" "Please commit or stash them."
# everything leading up to $branch) on top of $onto
# Now we are rebasing commits $upstream..$orig_head (or with --root,
# everything leading up to $orig_head) on top of $onto
# Check if we are already based on $onto with linear history, # Check if we are already based on $onto with linear history,
# but this should be done only when upstream and onto are the same. # but this should be done only when upstream and onto are the same
mb=$(git merge-base "$onto" "$branch") # and if this is not an interactive rebase.
if test "$upstream" = "$onto" && test "$mb" = "$onto" && mb=$(git merge-base "$onto" "$orig_head")
if test "$type" != interactive && test "$upstream" = "$onto" &&
test "$mb" = "$onto" &&
# linear history? # linear history?
! (git rev-list --parents "$onto".."$branch" | sane_grep " .* ") > /dev/null ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
then then
if test -z "$force_rebase" if test -z "$force_rebase"
then then
@ -522,10 +484,8 @@ then
fi fi
fi fi
# Detach HEAD and reset the tree # If a hook exists, give it a chance to interrupt
say "First, rewinding head to replay your work on top of it..." run_pre_rebase_hook "$upstream_arg" "$@"
git checkout -q "$onto^0" || die "could not detach HEAD"
git update-ref ORIG_HEAD $branch
if test -n "$diffstat" if test -n "$diffstat"
then then
@ -537,9 +497,16 @@ then
GIT_PAGER='' git diff --stat --summary "$mb" "$onto" GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi fi
test "$type" = interactive && run_specific_rebase
# Detach HEAD and reset the tree
say "First, rewinding head to replay your work on top of it..."
git checkout -q "$onto^0" || die "could not detach HEAD"
git update-ref ORIG_HEAD $orig_head
# If the $onto is a proper descendant of the tip of the branch, then # If the $onto is a proper descendant of the tip of the branch, then
# we just fast-forwarded. # we just fast-forwarded.
if test "$mb" = "$branch" if test "$mb" = "$orig_head"
then then
say "Fast-forwarded $branch_name to $onto_name." say "Fast-forwarded $branch_name to $onto_name."
move_to_original_branch move_to_original_branch
@ -553,51 +520,4 @@ else
revisions="$upstream..$orig_head" revisions="$upstream..$orig_head"
fi fi
if test -z "$do_merge" run_specific_rebase
then
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
--src-prefix=a/ --dst-prefix=b/ \
--no-renames $root_flag "$revisions" |
git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
ret=$?
test 0 != $ret -a -d "$GIT_DIR"/rebase-apply &&
echo $head_name > "$GIT_DIR"/rebase-apply/head-name &&
echo $onto > "$GIT_DIR"/rebase-apply/onto &&
echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head &&
echo "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet
exit $ret
fi
# start doing a rebase with git-merge
# this is rename-aware if the recursive (default) strategy is used
mkdir -p "$dotest"
echo "$onto" > "$dotest/onto"
echo "$onto_name" > "$dotest/onto_name"
prev_head=$orig_head
echo "$prev_head" > "$dotest/prev_head"
echo "$orig_head" > "$dotest/orig-head"
echo "$head_name" > "$dotest/head-name"
echo "$GIT_QUIET" > "$dotest/quiet"
msgnum=0
for cmt in `git rev-list --reverse --no-merges "$revisions"`
do
msgnum=$(($msgnum + 1))
echo "$cmt" > "$dotest/cmt.$msgnum"
done
echo 1 >"$dotest/msgnum"
echo $msgnum >"$dotest/end"
end=$msgnum
msgnum=1
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge

View file

@ -0,0 +1,30 @@
#!/bin/sh
#
# Copyright (c) 2010 Junio C Hamano.
#
. git-sh-setup
case "$action" in
continue)
git am --resolved --resolvemsg="$resolvemsg" &&
move_to_original_branch
exit
;;
skip)
git am --skip --resolvemsg="$resolvemsg" &&
move_to_original_branch
exit
;;
esac
test -n "$rebase_root" && root_flag=--root
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
--src-prefix=a/ --dst-prefix=b/ \
--no-renames $root_flag "$revisions" |
git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" &&
move_to_original_branch
ret=$?
test 0 != $ret -a -d "$state_dir" && write_basic_state
exit $ret

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,151 @@
#!/bin/sh
#
# Copyright (c) 2010 Junio C Hamano.
#
. git-sh-setup
prec=4
read_state () {
onto_name=$(cat "$state_dir"/onto_name) &&
end=$(cat "$state_dir"/end) &&
msgnum=$(cat "$state_dir"/msgnum)
}
continue_merge () {
test -d "$state_dir" || die "$state_dir directory does not exist"
unmerged=$(git ls-files -u)
if test -n "$unmerged"
then
echo "You still have unmerged paths in your index"
echo "did you forget to use git add?"
die "$resolvemsg"
fi
cmt=`cat "$state_dir/current"`
if ! git diff-index --quiet --ignore-submodules HEAD --
then
if ! git commit --no-verify -C "$cmt"
then
echo "Commit failed, please do not call \"git commit\""
echo "directly, but instead do one of the following: "
die "$resolvemsg"
fi
if test -z "$GIT_QUIET"
then
printf "Committed: %0${prec}d " $msgnum
fi
echo "$cmt $(git rev-parse HEAD^0)" >> "$state_dir/rewritten"
else
if test -z "$GIT_QUIET"
then
printf "Already applied: %0${prec}d " $msgnum
fi
fi
test -z "$GIT_QUIET" &&
GIT_PAGER='' git log --format=%s -1 "$cmt"
# onto the next patch:
msgnum=$(($msgnum + 1))
echo "$msgnum" >"$state_dir/msgnum"
}
call_merge () {
cmt="$(cat "$state_dir/cmt.$1")"
echo "$cmt" > "$state_dir/current"
hd=$(git rev-parse --verify HEAD)
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
msgnum=$(cat "$state_dir/msgnum")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
eval GITHEAD_$hd='$onto_name'
export GITHEAD_$cmt GITHEAD_$hd
if test -n "$GIT_QUIET"
then
GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
fi
test -z "$strategy" && strategy=recursive
eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
rv=$?
case "$rv" in
0)
unset GITHEAD_$cmt GITHEAD_$hd
return
;;
1)
git rerere $allow_rerere_autoupdate
die "$resolvemsg"
;;
2)
echo "Strategy: $strategy failed, try another" 1>&2
die "$resolvemsg"
;;
*)
die "Unknown exit code ($rv) from command:" \
"git-merge-$strategy $cmt^ -- HEAD $cmt"
;;
esac
}
finish_rb_merge () {
move_to_original_branch
git notes copy --for-rewrite=rebase < "$state_dir"/rewritten
if test -x "$GIT_DIR"/hooks/post-rewrite &&
test -s "$state_dir"/rewritten; then
"$GIT_DIR"/hooks/post-rewrite rebase < "$state_dir"/rewritten
fi
rm -r "$state_dir"
say All done.
}
case "$action" in
continue)
read_state
continue_merge
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge
exit
;;
skip)
read_state
git rerere clear
msgnum=$(($msgnum + 1))
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge
exit
;;
esac
mkdir -p "$state_dir"
echo "$onto_name" > "$state_dir/onto_name"
write_basic_state
msgnum=0
for cmt in `git rev-list --reverse --no-merges "$revisions"`
do
msgnum=$(($msgnum + 1))
echo "$cmt" > "$state_dir/cmt.$msgnum"
done
echo 1 >"$state_dir/msgnum"
echo $msgnum >"$state_dir/end"
end=$msgnum
msgnum=1
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
continue_merge
done
finish_rb_merge

View file

@ -9,7 +9,7 @@ except ImportError:
_digest = sha.new _digest = sha.new
import sys import sys
import os import os
sys.path.insert(0, os.getenv("GITPYTHONLIB","/usr/local/git/lib/python2.6/site-packages")) sys.path.insert(0, os.getenv("GITPYTHONLIB","/usr/local/git/lib/python2.7/site-packages"))
from git_remote_helpers.util import die, debug, warn from git_remote_helpers.util import die, debug, warn
from git_remote_helpers.git.repo import GitRepo from git_remote_helpers.git.repo import GitRepo

View file

@ -15,7 +15,6 @@ p show patch text as well
' '
. git-sh-setup . git-sh-setup
. git-parse-remote
GIT_PAGER= GIT_PAGER=
export GIT_PAGER export GIT_PAGER
@ -55,7 +54,7 @@ branch=$(git ls-remote "$url" \
p p
q q
}") }")
url=$(get_remote_url "$url") url=$(git ls-remote --get-url "$url")
if [ -z "$branch" ]; then if [ -z "$branch" ]; then
echo "warn: No branch of $url is at:" >&2 echo "warn: No branch of $url is at:" >&2
git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2 git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2

View file

@ -969,7 +969,7 @@ sub send_message {
@recipients = unique_email_list(@recipients,@cc,@bcclist); @recipients = unique_email_list(@recipients,@cc,@bcclist);
@recipients = (map { extract_valid_address($_) } @recipients); @recipients = (map { extract_valid_address($_) } @recipients);
my $date = format_2822_time($time++); my $date = format_2822_time($time++);
my $gitversion = '1.7.4'; my $gitversion = '1.7.6.1';
if ($gitversion =~ m/..GIT_VERSION../) { if ($gitversion =~ m/..GIT_VERSION../) {
$gitversion = Git::version(); $gitversion = Git::version();
} }
@ -1092,7 +1092,7 @@ X-Mailer: git-send-email $gitversion
"VALUES: server=$smtp_server ", "VALUES: server=$smtp_server ",
"encryption=$smtp_encryption ", "encryption=$smtp_encryption ",
"hello=$smtp_domain", "hello=$smtp_domain",
defined $smtp_server_port ? "port=$smtp_server_port" : ""; defined $smtp_server_port ? " port=$smtp_server_port" : "";
} }
if (defined $smtp_authuser) { if (defined $smtp_authuser) {

View file

@ -0,0 +1,29 @@
#!/bin/sh
#
# Copyright (c) 2010 Ævar Arnfjörð Bjarmason
#
# This is a skeleton no-op implementation of gettext for Git. It'll be
# replaced by something that uses gettext.sh in a future patch series.
if test -z "$GIT_GETTEXT_POISON"
then
gettext () {
printf "%s" "$1"
}
eval_gettext () {
printf "%s" "$1" | (
export PATH $(git sh-i18n--envsubst --variables "$1");
git sh-i18n--envsubst "$1"
)
}
else
gettext () {
printf "%s" "# GETTEXT POISON #"
}
eval_gettext () {
printf "%s" "# GETTEXT POISON #"
}
fi

Binary file not shown.

View file

@ -139,6 +139,13 @@ cd_to_toplevel () {
} }
} }
require_work_tree_exists () {
if test "z$(git rev-parse --is-bare-repository)" != zfalse
then
die "fatal: $0 cannot be used without a working tree."
fi
}
require_work_tree () { require_work_tree () {
test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true ||
die "fatal: $0 cannot be used without a working tree." die "fatal: $0 cannot be used without a working tree."

View file

@ -12,12 +12,14 @@ USAGE="list [<options>]
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC= OPTIONS_SPEC=
START_DIR=`pwd`
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree
cd_to_toplevel cd_to_toplevel
TMP="$GIT_DIR/.git-stash.$$" TMP="$GIT_DIR/.git-stash.$$"
trap 'rm -f "$TMP-*"' 0 TMPindex=${GIT_INDEX_FILE-"$GIT_DIR/index"}.stash.$$
trap 'rm -f "$TMP-"* "$TMPindex"' 0
ref_stash=refs/stash ref_stash=refs/stash
@ -81,14 +83,12 @@ create_stash () {
# state of the working tree # state of the working tree
w_tree=$( ( w_tree=$( (
rm -f "$TMP-index" && git read-tree --index-output="$TMPindex" -m $i_tree &&
cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" && GIT_INDEX_FILE="$TMPindex" &&
GIT_INDEX_FILE="$TMP-index" &&
export GIT_INDEX_FILE && export GIT_INDEX_FILE &&
git read-tree -m $i_tree &&
git diff --name-only -z HEAD | git update-index -z --add --remove --stdin && git diff --name-only -z HEAD | git update-index -z --add --remove --stdin &&
git write-tree && git write-tree &&
rm -f "$TMP-index" rm -f "$TMPindex"
) ) || ) ) ||
die "Cannot save the current worktree state" die "Cannot save the current worktree state"
@ -136,11 +136,12 @@ save_stash () {
keep_index=t keep_index=t
;; ;;
--no-keep-index) --no-keep-index)
keep_index= keep_index=n
;; ;;
-p|--patch) -p|--patch)
patch_mode=t patch_mode=t
keep_index=t # only default to keep if we don't already have an override
test -z "$keep_index" && keep_index=t
;; ;;
-q|--quiet) -q|--quiet)
GIT_QUIET=t GIT_QUIET=t
@ -185,7 +186,7 @@ save_stash () {
then then
git reset --hard ${GIT_QUIET:+-q} git reset --hard ${GIT_QUIET:+-q}
if test -n "$keep_index" && test -n $i_tree if test "$keep_index" = "t" && test -n $i_tree
then then
git read-tree --reset -u $i_tree git read-tree --reset -u $i_tree
fi fi
@ -193,7 +194,7 @@ save_stash () {
git apply -R < "$TMP-patch" || git apply -R < "$TMP-patch" ||
die "Cannot remove worktree changes" die "Cannot remove worktree changes"
if test -z "$keep_index" if test "$keep_index" != "t"
then then
git reset git reset
fi fi
@ -264,7 +265,7 @@ parse_flags_and_rev()
b_tree= b_tree=
i_tree= i_tree=
REV=$(git rev-parse --no-flags --symbolic "$@" 2>/dev/null) REV=$(git rev-parse --no-flags --symbolic "$@") || exit 1
FLAGS= FLAGS=
for opt for opt
@ -310,16 +311,6 @@ parse_flags_and_rev()
IS_STASH_LIKE=t && IS_STASH_LIKE=t &&
test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" && test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
IS_STASH_REF=t IS_STASH_REF=t
if test "${REV}" != "${REV%{*\}}"
then
# maintainers: it would be better if git rev-parse indicated
# this condition with a non-zero status code but as of 1.7.2.1 it
# it did not. So, we use non-empty stderr output as a proxy for the
# condition of interest.
test -z "$(git rev-parse "$REV" 2>&1 >/dev/null)" || die "$REV does not exist in the stash log"
fi
} }
is_stash_like() is_stash_like()
@ -344,9 +335,7 @@ apply_stash () {
assert_stash_like "$@" assert_stash_like "$@"
git update-index -q --refresh && git update-index -q --refresh || die 'unable to refresh index'
git diff-files --quiet --ignore-submodules ||
die 'Cannot apply to a dirty working tree, please stage your changes'
# current index state # current index state
c_tree=$(git write-tree) || c_tree=$(git write-tree) ||
@ -394,7 +383,7 @@ apply_stash () {
then then
squelch='>/dev/null 2>&1' squelch='>/dev/null 2>&1'
fi fi
eval "git status $squelch" || : (cd "$START_DIR" && eval "git status $squelch") || :
else else
# Merge conflict; keep the exit status from merge-recursive # Merge conflict; keep the exit status from merge-recursive
status=$? status=$?

View file

@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>] USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...] or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: $dashless [--quiet] init [--] [<path>...] or: $dashless [--quiet] init [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
or: $dashless [--quiet] foreach [--recursive] <command> or: $dashless [--quiet] foreach [--recursive] <command>
or: $dashless [--quiet] sync [--] [<path>...]" or: $dashless [--quiet] sync [--] [<path>...]"
@ -34,7 +34,7 @@ resolve_relative_url ()
{ {
remote=$(get_default_remote) remote=$(get_default_remote)
remoteurl=$(git config "remote.$remote.url") || remoteurl=$(git config "remote.$remote.url") ||
die "remote ($remote) does not have a url defined in .git/config" remoteurl=$(pwd) # the repository is its own authoritative upstream
url="$1" url="$1"
remoteurl=${remoteurl%/} remoteurl=${remoteurl%/}
sep=/ sep=/
@ -72,7 +72,24 @@ resolve_relative_url ()
# #
module_list() module_list()
{ {
git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 ' git ls-files --error-unmatch --stage -- "$@" |
perl -e '
my %unmerged = ();
my ($null_sha1) = ("0" x 40);
while (<STDIN>) {
chomp;
my ($mode, $sha1, $stage, $path) =
/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
next unless $mode eq "160000";
if ($stage ne "0") {
if (!$unmerged{$path}++) {
print "$mode $null_sha1 U\t$path\n";
}
next;
}
print "$_\n";
}
'
} }
# #
@ -104,12 +121,17 @@ module_clone()
path=$1 path=$1
url=$2 url=$2
reference="$3" reference="$3"
quiet=
if test -n "$GIT_QUIET"
then
quiet=-q
fi
if test -n "$reference" if test -n "$reference"
then then
git-clone "$reference" -n "$url" "$path" git-clone $quiet "$reference" -n "$url" "$path"
else else
git-clone -n "$url" "$path" git-clone $quiet -n "$url" "$path"
fi || fi ||
die "Clone of '$url' into submodule path '$path' failed" die "Clone of '$url' into submodule path '$path' failed"
} }
@ -221,15 +243,6 @@ cmd_add()
die "'$path' already exists and is not a valid git repo" die "'$path' already exists and is not a valid git repo"
fi fi
case "$repo" in
./*|../*)
url=$(resolve_relative_url "$repo") || exit
;;
*)
url="$repo"
;;
esac
git config submodule."$path".url "$url"
else else
module_clone "$path" "$realrepo" "$reference" || exit module_clone "$path" "$realrepo" "$reference" || exit
@ -243,6 +256,7 @@ cmd_add()
esac esac
) || die "Unable to checkout submodule '$path'" ) || die "Unable to checkout submodule '$path'"
fi fi
git config submodule."$path".url "$realrepo"
git add $force "$path" || git add $force "$path" ||
die "Failed to add submodule '$path'" die "Failed to add submodule '$path'"
@ -283,6 +297,10 @@ cmd_foreach()
toplevel=$(pwd) toplevel=$(pwd)
# dup stdin so that it can be restored when running the external
# command in the subshell (and a recursive call to this function)
exec 3<&0
module_list | module_list |
while read mode sha1 stage path while read mode sha1 stage path
do do
@ -299,7 +317,7 @@ cmd_foreach()
then then
cmd_foreach "--recursive" "$@" cmd_foreach "--recursive" "$@"
fi fi
) || ) <&3 3<&- ||
die "Stopping at '$path'; script returned non-zero status." die "Stopping at '$path'; script returned non-zero status."
fi fi
done done
@ -338,9 +356,8 @@ cmd_init()
do do
# Skip already registered paths # Skip already registered paths
name=$(module_name "$path") || exit name=$(module_name "$path") || exit
url=$(git config submodule."$name".url) if test -z "$(git config "submodule.$name.url")"
test -z "$url" || continue then
url=$(git config -f .gitmodules submodule."$name".url) url=$(git config -f .gitmodules submodule."$name".url)
test -z "$url" && test -z "$url" &&
die "No url found for submodule path '$path' in .gitmodules" die "No url found for submodule path '$path' in .gitmodules"
@ -351,12 +368,14 @@ cmd_init()
url=$(resolve_relative_url "$url") || exit url=$(resolve_relative_url "$url") || exit
;; ;;
esac esac
git config submodule."$name".url "$url" || git config submodule."$name".url "$url" ||
die "Failed to register url for submodule path '$path'" die "Failed to register url for submodule path '$path'"
fi
# Copy "update" setting when it is not set yet
upd="$(git config -f .gitmodules submodule."$name".update)" upd="$(git config -f .gitmodules submodule."$name".update)"
test -z "$upd" || test -z "$upd" ||
test -n "$(git config submodule."$name".update)" ||
git config submodule."$name".update "$upd" || git config submodule."$name".update "$upd" ||
die "Failed to register update mode for submodule path '$path'" die "Failed to register update mode for submodule path '$path'"
@ -385,6 +404,9 @@ cmd_update()
-N|--no-fetch) -N|--no-fetch)
nofetch=1 nofetch=1
;; ;;
-f|--force)
force=$1
;;
-r|--rebase) -r|--rebase)
update="rebase" update="rebase"
;; ;;
@ -423,9 +445,15 @@ cmd_update()
cmd_init "--" "$@" || return cmd_init "--" "$@" || return
fi fi
cloned_modules=
module_list "$@" | module_list "$@" |
while read mode sha1 stage path while read mode sha1 stage path
do do
if test "$stage" = U
then
echo >&2 "Skipping unmerged submodule $path"
continue
fi
name=$(module_name "$path") || exit name=$(module_name "$path") || exit
url=$(git config submodule."$name".url) url=$(git config submodule."$name".url)
update_module=$(git config submodule."$name".update) update_module=$(git config submodule."$name".update)
@ -442,6 +470,7 @@ cmd_update()
if ! test -d "$path"/.git -o -f "$path"/.git if ! test -d "$path"/.git -o -f "$path"/.git
then then
module_clone "$path" "$url" "$reference"|| exit module_clone "$path" "$url" "$reference"|| exit
cloned_modules="$cloned_modules;$name"
subsha1= subsha1=
else else
subsha1=$(clear_local_git_env; cd "$path" && subsha1=$(clear_local_git_env; cd "$path" &&
@ -456,19 +485,30 @@ cmd_update()
if test "$subsha1" != "$sha1" if test "$subsha1" != "$sha1"
then then
force= subforce=$force
if test -z "$subsha1" # If we don't already have a -f flag and the submodule has never been checked out
if test -z "$subsha1" -a -z "$force"
then then
force="-f" subforce="-f"
fi fi
if test -z "$nofetch" if test -z "$nofetch"
then then
# Run fetch only if $sha1 isn't present or it
# is not reachable from a ref.
(clear_local_git_env; cd "$path" && (clear_local_git_env; cd "$path" &&
git-fetch) || ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
test -z "$rev") || git-fetch)) ||
die "Unable to fetch in submodule path '$path'" die "Unable to fetch in submodule path '$path'"
fi fi
# Is this something we just cloned?
case ";$cloned_modules;" in
*";$name;"*)
# then there is no local change to integrate
update_module= ;;
esac
case "$update_module" in case "$update_module" in
rebase) rebase)
command="git rebase" command="git rebase"
@ -481,7 +521,7 @@ cmd_update()
msg="merged in" msg="merged in"
;; ;;
*) *)
command="git checkout $force -q" command="git checkout $subforce -q"
action="checkout" action="checkout"
msg="checked out" msg="checked out"
;; ;;
@ -761,6 +801,11 @@ cmd_status()
name=$(module_name "$path") || exit name=$(module_name "$path") || exit
url=$(git config submodule."$name".url) url=$(git config submodule."$name".url)
displaypath="$prefix$path" displaypath="$prefix$path"
if test "$stage" = U
then
say "U$sha1 $displaypath"
continue
fi
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
then then
say "-$sha1 $displaypath" say "-$sha1 $displaypath"
@ -831,6 +876,8 @@ cmd_sync()
;; ;;
esac esac
if git config "submodule.$name.url" >/dev/null 2>/dev/null
then
say "Synchronizing submodule url for '$name'" say "Synchronizing submodule url for '$name'"
git config submodule."$name".url "$url" git config submodule."$name".url "$url"
@ -843,6 +890,7 @@ cmd_sync()
git config remote."$remote".url "$url" git config remote."$remote".url "$url"
) )
fi fi
fi
done done
} }

View file

@ -9,7 +9,7 @@ use vars qw/ $AUTHOR $VERSION
$sha1 $sha1_short $_revision $_repository $sha1 $sha1_short $_revision $_repository
$_q $_authors $_authors_prog %users/; $_q $_authors $_authors_prog %users/;
$AUTHOR = 'Eric Wong <normalperson@yhbt.net>'; $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
$VERSION = '1.7.4'; $VERSION = '1.7.6.1';
# From which subdir have we been invoked? # From which subdir have we been invoked?
my $cmd_dir_prefix = eval { my $cmd_dir_prefix = eval {
@ -60,6 +60,7 @@ use File::Find;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use IPC::Open3; use IPC::Open3;
use Git; use Git;
use Memoize; # core since 5.8.0, Jul 2002
BEGIN { BEGIN {
# import functions from Git into our packages, en masse # import functions from Git into our packages, en masse
@ -73,6 +74,8 @@ BEGIN {
*{"${package}::$_"} = \&{"Git::$_"}; *{"${package}::$_"} = \&{"Git::$_"};
} }
} }
Memoize::memoize 'Git::config';
Memoize::memoize 'Git::config_bool';
} }
my ($SVN); my ($SVN);
@ -529,7 +532,7 @@ sub cmd_dcommit {
$url = eval { command_oneline('config', '--get', $url = eval { command_oneline('config', '--get',
"svn-remote.$gs->{repo_id}.commiturl") }; "svn-remote.$gs->{repo_id}.commiturl") };
if (!$url) { if (!$url) {
$url = $gs->full_url $url = $gs->full_pushurl
} }
} }
@ -677,7 +680,7 @@ sub cmd_branch {
$head ||= 'HEAD'; $head ||= 'HEAD';
my (undef, $rev, undef, $gs) = working_head_info($head); my (undef, $rev, undef, $gs) = working_head_info($head);
my $src = $gs->full_url; my $src = $gs->full_pushurl;
my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}}; my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}};
my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' }; my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' };
@ -728,7 +731,7 @@ sub cmd_branch {
$url = eval { command_oneline('config', '--get', $url = eval { command_oneline('config', '--get',
"svn-remote.$gs->{repo_id}.commiturl") }; "svn-remote.$gs->{repo_id}.commiturl") };
if (!$url) { if (!$url) {
$url = $remote->{url}; $url = $remote->{pushurl} || $remote->{url};
} }
} }
my $dst = join '/', $url, $lft, $branch_name, ($rgt || ()); my $dst = join '/', $url, $lft, $branch_name, ($rgt || ());
@ -782,6 +785,15 @@ sub cmd_find_rev {
print "$result\n" if $result; print "$result\n" if $result;
} }
sub auto_create_empty_directories {
my ($gs) = @_;
my $var = eval { command_oneline('config', '--get', '--bool',
"svn-remote.$gs->{repo_id}.automkdirs") };
# By default, create empty directories by consulting the unhandled log,
# but allow setting it to 'false' to skip it.
return !($var && $var eq 'false');
}
sub cmd_rebase { sub cmd_rebase {
command_noisy(qw/update-index --refresh/); command_noisy(qw/update-index --refresh/);
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD'); my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
@ -805,7 +817,9 @@ sub cmd_rebase {
$_fetch_all ? $gs->fetch_all : $gs->fetch; $_fetch_all ? $gs->fetch_all : $gs->fetch;
} }
command_noisy(rebase_cmd(), $gs->refname); command_noisy(rebase_cmd(), $gs->refname);
if (auto_create_empty_directories($gs)) {
$gs->mkemptydirs; $gs->mkemptydirs;
}
} }
sub cmd_show_ignore { sub cmd_show_ignore {
@ -1243,7 +1257,9 @@ sub post_fetch_checkout {
command_noisy(qw/read-tree -m -u -v HEAD HEAD/); command_noisy(qw/read-tree -m -u -v HEAD HEAD/);
print STDERR "Checked out HEAD:\n ", print STDERR "Checked out HEAD:\n ",
$gs->full_url, " r", $gs->last_rev, "\n"; $gs->full_url, " r", $gs->last_rev, "\n";
if (auto_create_empty_directories($gs)) {
$gs->mkemptydirs($gs->last_rev); $gs->mkemptydirs($gs->last_rev);
}
} }
sub complete_svn_url { sub complete_svn_url {
@ -1832,6 +1848,8 @@ sub read_all_remotes {
$r->{$1}->{svm} = {}; $r->{$1}->{svm} = {};
} elsif (m!^(.+)\.url=\s*(.*)\s*$!) { } elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
$r->{$1}->{url} = $2; $r->{$1}->{url} = $2;
} elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
$r->{$1}->{pushurl} = $2;
} elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) { } elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
my ($remote, $t, $local_ref, $remote_ref) = my ($remote, $t, $local_ref, $remote_ref) =
($1, $2, $3, $4); ($1, $2, $3, $4);
@ -2069,6 +2087,8 @@ sub new {
$self->{url} = command_oneline('config', '--get', $self->{url} = command_oneline('config', '--get',
"svn-remote.$repo_id.url") or "svn-remote.$repo_id.url") or
die "Failed to read \"svn-remote.$repo_id.url\" in config\n"; die "Failed to read \"svn-remote.$repo_id.url\" in config\n";
$self->{pushurl} = eval { command_oneline('config', '--get',
"svn-remote.$repo_id.pushurl") };
$self->rebuild; $self->rebuild;
$self; $self;
} }
@ -2546,6 +2566,15 @@ sub full_url {
$self->{url} . (length $self->{path} ? '/' . $self->{path} : ''); $self->{url} . (length $self->{path} ? '/' . $self->{path} : '');
} }
sub full_pushurl {
my ($self) = @_;
if ($self->{pushurl}) {
return $self->{pushurl} . (length $self->{path} ? '/' .
$self->{path} : '');
} else {
return $self->full_url;
}
}
sub set_commit_header_env { sub set_commit_header_env {
my ($log_entry) = @_; my ($log_entry) = @_;
@ -3096,8 +3125,12 @@ sub lookup_svn_merge {
next; next;
} }
if (scalar(command('rev-parse', "$bottom_commit^@"))) {
push @merged_commit_ranges, push @merged_commit_ranges,
"$bottom_commit^..$top_commit"; "$bottom_commit^..$top_commit";
} else {
push @merged_commit_ranges, "$top_commit";
}
if ( !defined $tip or $top > $tip ) { if ( !defined $tip or $top > $tip ) {
$tip = $top; $tip = $top;
@ -3126,9 +3159,9 @@ sub check_cherry_pick {
my $parents = shift; my $parents = shift;
my @ranges = @_; my @ranges = @_;
my %commits = map { $_ => 1 } my %commits = map { $_ => 1 }
_rev_list("--no-merges", $tip, "--not", $base, @$parents); _rev_list("--no-merges", $tip, "--not", $base, @$parents, "--");
for my $range ( @ranges ) { for my $range ( @ranges ) {
delete @commits{_rev_list($range)}; delete @commits{_rev_list($range, "--")};
} }
for my $commit (keys %commits) { for my $commit (keys %commits) {
if (has_no_changes($commit)) { if (has_no_changes($commit)) {
@ -3198,6 +3231,8 @@ sub has_no_changes {
Memoize::unmemoize 'check_cherry_pick'; Memoize::unmemoize 'check_cherry_pick';
Memoize::unmemoize 'has_no_changes'; Memoize::unmemoize 'has_no_changes';
} }
Memoize::memoize 'Git::SVN::repos_root';
} }
END { END {
@ -5735,7 +5770,7 @@ sub cmd_show_log {
my (@k, $c, $d, $stat); my (@k, $c, $d, $stat);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/; my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) { while (<$log>) {
if (/^${esc_color}commit -?($::sha1_short)/o) { if (/^${esc_color}commit (?:- )?($::sha1_short)/o) {
my $cmt = $1; my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) { if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r}; $r_last = $c->{r};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
/BinaryCache/Git/Git-19~1/Root/usr/share/git-core/perl/Git.pm
/BinaryCache/Git/Git-19~1/Root/usr/share/man/man3/Git.3pm

View file

@ -113,7 +113,7 @@ namespace SparkleShare {
if (FirstRun) if (FirstRun)
SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.TrueString); SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.TrueString);
else else
AddKey (); ImportPrivateKey ();
// Watch the SparkleShare folder // Watch the SparkleShare folder
FileSystemWatcher watcher = new FileSystemWatcher (SparkleConfig.DefaultConfig.FoldersPath) { FileSystemWatcher watcher = new FileSystemWatcher (SparkleConfig.DefaultConfig.FoldersPath) {
@ -247,7 +247,7 @@ namespace SparkleShare {
if (name == null) if (name == null)
return GetLog (); return GetLog ();
string path = new string [] {SparkleConfig.DefaultConfig.FoldersPath, name}.Combine (); string path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, name);
int log_size = 50; int log_size = 50;
foreach (SparkleRepoBase repo in Repositories) { foreach (SparkleRepoBase repo in Repositories) {
@ -749,7 +749,7 @@ namespace SparkleShare {
// Adds the user's SparkleShare key to the ssh-agent, // Adds the user's SparkleShare key to the ssh-agent,
// so all activity is done with this key // so all activity is done with this key
public void AddKey () public void ImportPrivateKey ()
{ {
string keys_path = Path.GetDirectoryName (SparkleConfig.DefaultConfig.FullPath); string keys_path = Path.GetDirectoryName (SparkleConfig.DefaultConfig.FullPath);
string key_file_name = "sparkleshare." + UserEmail + ".key"; string key_file_name = "sparkleshare." + UserEmail + ".key";

View file

@ -84,10 +84,12 @@ namespace SparkleShare {
get { get {
List<SparkleChangeSet> change_sets = Program.Controller.GetLog (this.selected_folder); List<SparkleChangeSet> change_sets = Program.Controller.GetLog (this.selected_folder);
string html = Program.Controller.GetHTMLLog (change_sets);
if (UpdateSizeInfoEvent != null) if (UpdateSizeInfoEvent != null)
UpdateSizeInfoEvent (Size, HistorySize); UpdateSizeInfoEvent (Size, HistorySize);
return Program.Controller.GetHTMLLog (change_sets); return html;
} }
} }

View file

@ -184,6 +184,7 @@ namespace SparkleShare {
Program.Controller.UserEmail = email; Program.Controller.UserEmail = email;
Program.Controller.GenerateKeyPair (); Program.Controller.GenerateKeyPair ();
Program.Controller.ImportPrivateKey ();
Program.Controller.UpdateState (); Program.Controller.UpdateState ();
if (ChangePageEvent != null) if (ChangePageEvent != null)

View file

@ -103,7 +103,10 @@ namespace SparkleShare {
case IconState.Syncing: case IconState.Syncing:
StateText = _("Syncing…"); StateText = _("Syncing… ") +
Controller.ProgressPercentage + "% " +
Controller.ProgressSpeed;
UpdateStateText (); UpdateStateText ();
if (!Animation.Enabled) if (!Animation.Enabled)

View file

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 622 B

View file

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 639 B

View file

Before

Width:  |  Height:  |  Size: 643 B

After

Width:  |  Height:  |  Size: 643 B

View file

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 641 B

View file

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 637 B

View file

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

View file

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

View file

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 652 B

View file

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 652 B

View file

Before

Width:  |  Height:  |  Size: 662 B

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

View file

Before

Width:  |  Height:  |  Size: 540 B

After

Width:  |  Height:  |  Size: 540 B

View file

Before

Width:  |  Height:  |  Size: 613 B

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 913 KiB

After

Width:  |  Height:  |  Size: 952 KiB