是否由于日期变更而由于错误的基准而删除了未推送的重复git提交?

时间:2018-10-02 11:16:32

标签: git

我一直在尝试修改未推送提交的时间戳,并犯了一个错误(没有创建新的分支并合并,而不是重新设置--continue),这导致尚未推送的提交重复。这是一个模拟问题的bash脚本,例如test.sh

rm -rf mytestgit
mkdir mytestgit
cd mytestgit
git init
git config user.email "you@example.com"
git config user.name "Your Name"

SLEEPTIME=5

git commit --allow-empty -m 'first commit'
echo " (... wait ...) "; sleep $SLEEPTIME
git commit --allow-empty -m 'second commit'
echo " (... wait ...) "; sleep $SLEEPTIME
THIRDC=$(git commit --allow-empty -m 'third commit')
echo $THIRDC
echo " (... wait ...) "; sleep $SLEEPTIME
git commit --allow-empty -m 'fourth commit'

git status

git --no-pager log --graph --abbrev-commit --all --decorate --pretty=format:"%h%x09%an%x09%ad%x09%s %d" ; echo # add '\n' at end
GLOGLAST=$(git --no-pager log -1 --graph --abbrev-commit --all --decorate --pretty=format:"%h%x09%an%x09%ad%x09%s %d")
IFS=+ read left SPLITGLLA <<< "$GLOGLAST"
IFS="   " read SPLITGLL right  <<< "$SPLITGLLA" # this is TAB here, not space, for IFS
TIMEZONE=${SPLITGLL[0]}
SPLITTC=(${THIRDC//]/ })
THIRDCHASH="${SPLITTC[1]}"
THIRDCUTS=$(git show -s --format=%ct $THIRDCHASH)
THIRDCUTSNEW=$((THIRDCUTS-3))
echo "Third commit hash: $THIRDCHASH, Unix timestamp $THIRDCUTS, timezone +$TIMEZONE, new Unix timestamp (three seconds earlier) $THIRDCUTSNEW"
echo

# cd mytestgit # already in
# here choose $THIRDCHASH with e, saving and closing text editor
git rebase $THIRDCHASH^ -i --keep-empty
GIT_COMMITTER_DATE="$THIRDCUTSNEW +$TIMEZONE" git commit --amend --no-edit --allow-empty --date "$THIRDCUTSNEW +$TIMEZONE"

# here the mistake
git checkout -b newbranch
git checkout master
git merge newbranch
git branch -d newbranch

# check final state
git --no-pager log --graph --abbrev-commit --all --decorate --pretty=format:"%h%x09%an%x09%ad%x09%s %d" ; echo # add '\n' at end

运行此脚本时,得到以下输出:

Initialized empty Git repository in /tmp/mytestgit/.git/
[master (root-commit) 1a5fa9a] first commit
 (... wait ...) 
[master f6b51cc] second commit
 (... wait ...) 
[master f9871cc] third commit
 (... wait ...) 
[master cfd0208] fourth commit
On branch master
nothing to commit, working directory clean
* cfd0208   Your Name   Tue Oct 2 13:05:00 2018 +0200   fourth commit  (HEAD, master)
* f9871cc   Your Name   Tue Oct 2 13:04:55 2018 +0200   third commit 
* f6b51cc   Your Name   Tue Oct 2 13:04:50 2018 +0200   second commit 
* 1a5fa9a   Your Name   Tue Oct 2 13:04:45 2018 +0200   first commit 
Third commit hash: f9871cc, Unix timestamp 1538478295, timezone +0200, new Unix timestamp (three seconds earlier) 1538478292

Stopped at f9871cca92f2e3da587fa8b16021f8e52976c8d9... third commit
You can amend the commit now, with

    git commit --amend

Once you are satisfied with your changes, run

    git rebase --continue

...然后在重新定位时,我将其放在自动启动的文本编辑器中(将第一个pick更改为e):

e f9871cc third commit
pick cfd0208 fourth commit

# Rebase f6b51cc..cfd0208 onto f6b51cc
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

...保存,然后退出文本编辑器-脚本继续:

[detached HEAD 63e35fe] third commit
Switched to a new branch 'newbranch'
Switched to branch 'master'

...并且在错误合并时,我在自动启动的文本编辑器中得到了此信息:

Merge branch 'newbranch'

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

...我将其保存而不进行任何更改,然后退出文本编辑器-脚本以显示最终状态结束:

Already up-to-date!
Merge made by the 'recursive' strategy.
Deleted branch newbranch (was 63e35fe).
*   9b1ac28 Your Name   Tue Oct 2 13:05:36 2018 +0200   Merge branch 'newbranch'  (HEAD, master)
|\  
| * 63e35fe Your Name   Tue Oct 2 13:04:52 2018 +0200   third commit 
* | cfd0208 Your Name   Tue Oct 2 13:05:00 2018 +0200   fourth commit 
* | f9871cc Your Name   Tue Oct 2 13:04:55 2018 +0200   third commit 
|/  
* f6b51cc   Your Name   Tue Oct 2 13:04:50 2018 +0200   second commit 
* 1a5fa9a   Your Name   Tue Oct 2 13:04:45 2018 +0200   first commit 

因此,现在我有重复的提交(63e35fe“第三次提交”)和合并提交(9b1ac28“合并分支'newbranch'”),而不是重复的“第四次提交”。

基本上,我已经将第二个提交和第一个提交推送到了在线仓库中,但是尚未提交第三个和第四个提交。

如何删除重复项(63e35fe“第三次提交”,它以更改的时间戳记结束,而不是原始的f9871cc“第三次提交”)并额外合并(9b1ac28“合并分支'newbranch'” )提交,这样我就不会最终将它们推入仓库了?

或者换句话说,如何在git rebase $THIRDCHASH^ -i --keep-empty命令运行之前将存储库的状态恢复到-所以我可以重新运行它,并使用git rebase --continue正确地结束它而不是合并,这样我就可以在线推送“原始”提交(而不是重复的/附加的)吗?

1 个答案:

答案 0 :(得分:0)

事实证明,在OP结束的状态下,仍然存在一个rebase-merge目录:

$ git rebase f6b51cc^ -i --keep-empty

It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase.  If that is the
case, please try
    git rebase (--continue | --abort | --skip)
If that is not the case, please
    rm -fr "/tmp/mytestgit/.git/rebase-merge"
and run me again.  I am stopping in case you still have something
valuable there.

...还有我已经做完而又忘记提及的另一步骤是:

rm -fr "/tmp/mytestgit/.git/rebase-merge"

...然后显示以下图形:

$ git --no-pager log --graph --abbrev-commit --all --decorate --pretty=format:"%h%x09%an%x09%ad%x09%s %d" ; echo
* 93bf274   Your Name   Tue Oct 2 13:05:00 2018 +0200   fourth commit  (HEAD, master)
*   9b1ac28 Your Name   Tue Oct 2 13:05:36 2018 +0200   Merge branch 'newbranch' 
|\  
| * 63e35fe Your Name   Tue Oct 2 13:04:52 2018 +0200   third commit 
* | cfd0208 Your Name   Tue Oct 2 13:05:00 2018 +0200   fourth commit 
* | f9871cc Your Name   Tue Oct 2 13:04:55 2018 +0200   third commit 
|/  
* f6b51cc   Your Name   Tue Oct 2 13:04:50 2018 +0200   second commit 
* 1a5fa9a   Your Name   Tue Oct 2 13:04:45 2018 +0200   first commit 

然后,我对git rebase f6b51cc^ -i --keep-empty进行了以下操作:

pick f6b51cc second commit
pick f9871cc third commit
pick cfd0208 fourth commit
#pick 63e35fe third commit
#pick 93bf274 fourth commit

# Rebase 1a5fa9a..93bf274 onto 1a5fa9a
#
# Commands:
...

...因此删除了63e35fe和93bf274(请注意,9b1ac28“合并分支'newbranch'”不在给定列表中),结果是:

Successfully rebased and updated refs/heads/master.

...,这里的状态是:

$ git --no-pager log --graph --abbrev-commit --all --decorate --pretty=format:"%h%x09%an%x09%ad%x09%s %d" ; echo
* cfd0208   Your Name   Tue Oct 2 13:05:00 2018 +0200   fourth commit  (HEAD, master)
* f9871cc   Your Name   Tue Oct 2 13:04:55 2018 +0200   third commit 
* f6b51cc   Your Name   Tue Oct 2 13:04:50 2018 +0200   second commit 
* 1a5fa9a   Your Name   Tue Oct 2 13:04:45 2018 +0200   first commit 

...这是第一次重新设置之前的状态(应该已经更改了时间戳),这就是我想要的。