Opened 8 years ago
Closed 8 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 )
Steps to reproduce:
- Clone a repo from some origin.
- Commit something to origin.
- Commit something to your local clone.
- 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)
Change History (5)
comment:1 by , 8 years ago
Description: | modified (diff) |
---|
by , 8 years ago
Attachment: | git-2017030917572061.log added |
---|
comment:2 by , 8 years ago
comment:3 by , 8 years ago
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
callsgit rebase --am
git rebase --am
generates a cumulative patch to apply on top of the remote branchgit rebase --am
callsgit am --rebasing
to apply this patchgit am --rebasing
callsgit mailsplit
usingfork()
to split the patch into separate filesgit 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 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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.
Running
git pull -v -v -v --rebase
from underset GIT_TRACE=1
reveals an attached log file. The last command isgit gc --auto
which, according to #55, is broken long ago. So this may be a thing that stopspull --rebase
from working as well.