Skip to content

Instantly share code, notes, and snippets.

@kuceb
Created June 5, 2020 16:27
Show Gist options
  • Save kuceb/c6340b0406e6f3fc4bbdb212064c94cf to your computer and use it in GitHub Desktop.
Save kuceb/c6340b0406e6f3fc4bbdb212064c94cf to your computer and use it in GitHub Desktop.
a better git merge-tree for printing merge conflicts
#!/usr/bin/perl
use strict;
use Term::ANSIColor;
$ARGV[1] = $ARGV[1] || 'HEAD';
my $mb = `git merge-base $ARGV[0] $ARGV[1]`;
# trim ()
$mb =~ s/^\s+//;
$mb =~ s/\s+$//;
my $cmd = "git merge-tree $mb $ARGV[1] $ARGV[0]";
my $str = `$cmd`."\ny";
my $regex = qr/^(changed in both|removed in local|removed in remote|added in both)\n([\s\S\r]*?)(?=\n[rcyam])/mp;
my @files = ();
while ( $str =~ /$regex/g ) {
if ($1 eq "changed in both" or $1 eq "added in both") {
my $reason = $1;
my $str2 = $2;
my $rg2 = qr/^\+<<<<<<<.*^\+======.*^\+>>>>>>>/msp;
if ($str2 =~ /$rg2/g) {
my $rg_getfile = qr/^ our\s+\w+\s+\w+\s(\S+)/msp;
if ($str2 =~ /$rg_getfile/) {
if ($reason eq "changed in both") {
push(@files, "both modified: $1\n");
# push(@files, colored("\nboth modified:", "red")." $1");
} else {
# added in both
push(@files, "both added: $1\n");
# push(@files, colored("\n$reason:", "red")." $1");
}
}
}
} elsif ($1 eq "removed in local") {
my $str2 = $2;
my $rg2 = qr/^ base\s+\w+\s+(\w+).*^ their\s+\w+\s(\w+)\s(\S+)/msp;
if ( $str2 =~ /$rg2/g ) {
if ($1 ne $2) {
push(@files, "deleted by us: $3\n")
# push(@files, colored("\ndeleted by us:", "red")." $3")
}
} else {
push(@files, "couldn't parse changes from 'removed in local'\n")
}
} elsif ($1 eq "removed in remote") {
my $str2 = $2;
my $rg2 = qr/^ base\s+\w+\s+(\w+).*^ our\s+\w+\s(\w+)\s(\S+)/msp;
if ($str2 =~ /$rg2/g) {
if ($1 ne $2) {
push(@files, "deleted by them: $3\n")
# push(@files, colored("\ndeleted by them:", "red")." $3")
}
}
}
}
print @files
@kuceb
Copy link
Author

kuceb commented Jun 5, 2020

Usage examples:

preview merge conflicts that will happen merging origin/master into HEAD:

git-merge-tree.pl origin/master

git-merge-tree.pl master output before merge:
image

git status after git merge master:
20-06-05_12:37::34

review merge conflicts that had to be resolved in <merge-commit-sha>:

git-merge-tree.pl origin/master <merge-commit-sha>^

NOTE: unfortunately renames will show up as deleted from this script, when they would actually be auto-merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment