Re: [PATCH] rebase: be cleverer with rebased upstream branches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 16, 2011 at 1:10 PM, Santi Béjar <santi@xxxxxxxxxxx> wrote:
> On Wed, Feb 16, 2011 at 3:03 AM, Martin von Zweigbergk
> <martin.von.zweigbergk@xxxxxxxxx> wrote:
>> On Tue, 15 Feb 2011, Junio C Hamano wrote:
>>
>>> Would bisection help to avoid the cost?
>>
>> I don't think the straight-forward use of bisection would work. If the
>> history looks something like below, where 'b' is the branch to rebase
>> and 'u' is the upstream, we have to go through each entry in the
>> reflog to find u@{3}.
>>
>>
>>        .-u@{0}
>>       /
>>      .---u@{1}
>>     /
>> x---y-----u@{2}
>>     \
>>      .---u@{3}---b
>>       \
>>        .-u@{4}
>>
>>
>> I have an idea inspired by bisection, Thomas's exponential stride, and
>> what someone (you?) mentioned the other day about virtual merge
>> commits. I haven't tried it out, but let me know what you think. I'll
>> try to explain it using an example only:
>>
>> Exponential stride phase:
>> 1. candidates={ u@{0} }
>>   merge-base b $candidates -> y, _not_ in $candidates
>> 2. candidates={ u@{1} u@{2} }
>>   merge-base b $candidates -> y, _not_ in $candidates
>> 3. candidates={ u@{3} u@{4} u@{5} u@{6} }
>>   merge-base b $candidates -> u@{3}, in $candidates
>
> Doesn't it indicate that u@{3} is the commit we are looking for? I
> haven't found a counterexample...
>
> If this is true the following patch can implement it for git-pull.sh and
> git-rebase.sh (sorry if it is space damaged):
>
> diff --git i/git-pull.sh w/git-pull.sh
> index 2cdea26..09ef0a9 100755
> --- i/git-pull.sh
> +++ w/git-pull.sh
> @@ -189,14 +189,7 @@ test true = "$rebase" && {
>        . git-parse-remote &&
>        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
>        oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
> -       for reflog in $(git rev-list -g $remoteref 2>/dev/null)
> -       do
> -               if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
> -               then
> -                       oldremoteref="$reflog"
> -                       break
> -               fi
> -       done
> +       oldremoteref=$(git merge-base $curr_branch $oldremoteref $(git
> rev-list -g $remoteref 2>/dev/null))

One thing I forgot to say is that it seems to perform quite well:

Hot cache:

$ git rev-list -g origin/next | wc -l
36
$ git rev-list -g origin/master | wc -l
52
$ time git merge-base $(git rev-list -g origin/next)
3b781df0a25d5ba23bd2603b0e3e9bb4731369df

real	0m0.155s
user	0m0.064s
sys	0m0.044s
$ time git merge-base $(git rev-list -g origin/master)
7811d9600f02e70c9f835719c71156c967a684f7

real	0m0.161s
user	0m0.064s
sys	0m0.040s
$ time git merge-base $(git rev-list -g origin/master origin/master)
7811d9600f02e70c9f835719c71156c967a684f7

real	0m0.175s
user	0m0.076s
sys	0m0.036s

Cold-cache around 1 second. And it's not linear with the number of
reflog entries, but with the number of independent branches, I
suppose.

HTH,
Santi

P.D.: Attached is the patch, in case someone wants to try it.

Attachment: patch
Description: Binary data


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]