Opened 7 years ago

Closed 7 years ago

#146 closed defect (fixed)

git: pull --rebase does not work

Reported by: dmik Owned by:
Priority: major Milestone:
Component: git Version:
Severity: medium Keywords:
Cc:

Description (last modified by dmik)

Steps to reproduce:

  1. Clone a repo from some origin.
  2. Commit something to origin.
  3. Commit something to your local clone.
  4. Run git pull --rebase.

It is expected that git temporarily discards commits from step 3, then pulls all commits from step 2 and then applies commits from step 3 on top of the result. This is all needed to push your local changes w/o creating a special merge commit (which a regular git pull would create) in case if there were remote changes that you don't have (because you didn't do git pull before committing new local stuff).

However, git just says this:

First, rewinding head to replay your work on top of it...

and then exits. And your working repo is left in a state when remote commits are applied but all your local commits are NOT restored on top of them (i.e. they are virtually lost unless you know git internals well enough to get them from your rev-log).

If your local clone is behind origin by several commits and you make a local commit which you want to push

Attachments (1)

git-2017030917572061.log (6.7 KB) - added by dmik 7 years ago.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 7 years ago by dmik

Description: modified (diff)

Changed 7 years ago by dmik

Attachment: git-2017030917572061.log added

comment:2 Changed 7 years ago by dmik

Running git pull -v -v -v --rebase from under set GIT_TRACE=1 reveals an attached log file. The last command is git gc --auto which, according to #55, is broken long ago. So this may be a thing that stops pull --rebase from working as well.

comment:3 Changed 7 years ago by dmik

Turns out that this is a 'stdout not flushed' issue (see https://github.com/bitwiseworks/libcx/issues/31 for details). What happens here is the following:

  • git pull --rebase calls git rebase --am
  • git rebase --am generates a cumulative patch to apply on top of the remote branch
  • git rebase --am calls git am --rebasing to apply this patch
  • git am --rebasing calls git mailsplit using fork() to split the patch into separate files
  • git mailsplit outputs the number of files it creates to stdout
  • the fork parent reads child's stdout through a pipe (implemented with socketpair on OS/2)
  • sometimes (depending on some timing) stdout happens to be not properly flushed by the child before termination (see the above issue) so the parent reads nothing and thinks there are 0 mail files

As a result, patch files are not processed and therefore not applied (which explains why there is no Applying: COMMIT messages in the git pull --rebase output). A simple workaround that does setvbuf(stdout, NULL, _IONBF, 0); in the git main implementation solves the problem but I will try to find an ultimate solution within LIBCx issue 31 (see above).

comment:4 Changed 7 years ago by dmik

Resolution: fixed
Status: newclosed

This is fixed within https://github.com/bitwiseworks/libcx/issues/31. Now all works as it should, at least on my test repository. We will test it in real life over time. A fix will be available for everyone with a new git and libcx RPM release shortly.

Note: See TracTickets for help on using tickets.