2010-02-01 3 views
38

Как я могу узнать, какие коммиты на самом деле будет перенаправлен в удаленный репозиторий?Предварительный просмотр Git push

Насколько я знаю, всякий раз, когда я вытаскиваю мастер из удаленного репозитория, коммиты, скорее всего, будут сгенерированы, даже если они пусты.

Это приводит к тому, что локальный хозяин будет «вперед», даже если на самом деле ничего не нажать.

Теперь, если я пытаюсь (от мастера):

git cherry origin master 

У меня есть представление о том, что будет нажата, хотя это также отображать некоторые коммиты, которые я уже сдвинуты. Есть ли способ отобразить только новый контент, который будет нажат?

ответ

24

Помните origin/master является ссылка, которая указывает на голову главного отделения на пульте дистанционного управления имени origin на последнем тянуть, так что вы можете использовать такие команды, как

$ git log origin/master..master 

Вы можете использовать git-preview-push ниже, что комментарии на выходе git push --dry-run --porcelain:

#! /usr/bin/env perl 

use warnings; 
use strict; 

die "Usage: $0 remote refspec\n" unless @ARGV == 2; 
my($origin,$refspec) = @ARGV; 
my @cmd = qw/ git push --dry-run --porcelain /; 
no warnings 'exec'; 
open my $fh, "-|" => @cmd, $origin, $refspec or die "$0: exec: $!"; 
# <flag> \t <from>:<to> \t <summary> (<reason>) 
my $update = qr/^ (.*)   \t # flag (optional) 
        (\S+):(\S+) \t # from:to 
        (.+)    # summary 
        (?:[ ] \((.+)\))? # reason 
       $/x; 

while (<$fh>) { 
    next unless my($flag,$from,$to,$summary,$reason) = /$update/; 
    if ($flag eq "!") { 
    print "$0: $refspec rejected:\n", $_; 
    } 
    elsif ($flag eq "=") { 
    print "$0: $refspec up-to-date\n"; 
    } 
    if ($summary =~ /^[0-9a-f]+\.\.[0-9a-f]+$/) { 
    system("git log --pretty=oneline $summary") == 0 
     or warn "$0: git log exited " . ($? >> 8); 
    } 
    elsif ($summary eq "[new branch]") { 
    print "$0: $refspec creates a new branch.\n"; 
    } 
} 

Пример использования:

$ git preview-push /tmp/bare master 
To /tmp/bare 
270f8e6bec7af9b2509710eb1ae986a8e97068ec baz 
4c3d1e89f5d6b0d493c9d0c7a06420d6b2eb5af7 bar
+1

+1, но мне придется попасть на мой soapbox около #!/Usr/bin/env perl, так как я только что сгорел bugzilla, используя #!/Usr/bin/perl, когда я устанавливал модули в/usr/local/bin/perl и пришлось временно сделать/usr/bin/perl символическую ссылку на/usr/local/bin/perl –

+5

+1 «git log origin/master..master» достаточно в большинстве случаев. –

+0

@William Исправлено! –

0

Если вы уронили это в свой профиле Bash вы будете иметь возможность запускать усмешку (Git удаленного входящий) и затирки (Git удаленных исходящий), чтобы увидеть коммиты посмотреть различие, которые являются входящими и исходящими для ведущего происхождения:

function parse_git_branch { 
    git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' 
} 

function gd2 { 
    echo branch \($1\) has these commits and \($2\) does not 
    git log $2..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local 
} 

function grin { 
    git fetch origin master 
    gd2 FETCH_HEAD $(parse_git_branch) 
} 

function grout { 
    git fetch origin master 
    gd2 $(parse_git_branch) FETCH_HEAD 
} 
5

Я написал инструмент для этого, называемый git wtf: https://github.com/michaelklishin/git-wtf. Цвета и все такое!

В качестве бонуса он также покажет вам связь между ветвью функций и ветвью интеграции.

2

Я добавил следующие псевдонимы моего ~/.gitconfig, чтобы показать, что будут объединены (во время рывка), что будет нажата, и псевдоним для дифф против дистанционного управления:

[alias] 
     # diff remote branch (e.g., git diff origin/master master) 
     difr = "diff @{u}" 

     # similar to hg incoming/outgoing, showing what would be pulled/pushed 
     # use option "-p" to see actual patch 
     incoming = "!git remote update -p; git log [email protected]{u}" 

     # showing what would be pushed (see also alias difr) 
     outgoing = log @{u}..