git rebase 相关内容

本来也是不打算写这个,但是考虑到这个用得比较少,刚好也可以小结一下。背景是这样的:现在有一个git仓库,前面有很多提交,然后前面的提交中没有对数据库密码加密,所以我打算丢弃到前面这些提交(准确来说应该是合并成一个提交),只保留第一个提交和最后一个提交或者只保留最后一个提交

手段1,暴力解决

点击显/隐内容

something you want to fold, include code block.

手工方式

手工保留一份当前代码(不包含.git的文件夹和其他IDE相关的文件),然后切换到初始提交的位置,手工将刚才复制出来的代码粘贴进去,然后提交,因为是detached,也就是分离的头指针,把当前分支做成master分支,直接push -f就搞定了。但是这种方式过于憨批,而且绝大多数公司都禁止使用-f参数。当然暴力的方式应该有一堆

干掉.git文件夹

比如还可以将.git文件夹干掉,重新init一个,然后直接添加远端地址为刚才那个地址,使用-f参数,直接覆盖(没试过,感觉理论上好像可行)。

使用reset

或者更憨批的方式直接使用reset到init提交的位置,然后直接commit,push的时候理论上应该还是应该加上-f参数,否则应该会有合并操作需要做,但是我们不需要所以这个也应该算是暴力的方式.

手工方式升级版

checkout init提交,这个时候应该是分离的头指针,然后让这个提交去合并最后一次的提交,合并操作完成后有一个新的提交出来,然后强行把当前分支搞成master分支,然后branch -d 干掉先前的那个master分支,然后就是提交,应该也要加-f参数

使用rebase(中文翻译为变基)

这个方式才是正道,前面的几种全是歪门邪道,全是我yy出来的,我都没完整的试过,(只试了一点其中的几步)大多数全是凭感觉想象应该会出现什么情况。但是这个解决方案才是会被使用的,我在后面也会加上详细的步骤。

使用

看看历史log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ git log --oneline --graph --all
* dd74e4f (HEAD -> master, origin/master, origin/HEAD) refactor(application properties): use jasypt to hidden databa
* 440caf5 error need to solve
* cedc0b9 feat(security): update securtiy
* f6a8f34 build(properties): add prod properties
* 0f67f6b 'formate'
* dea7958 almost down
* 45ae82a 周六
* 3707932 add spring security
| * a4ffb37 (refs/stash) On master: Uncommitted changes before Update at 2019-7-26 9:15
| |\
|/ /
| * 7a42620 index on master: 8ce8dc3 add image verification test
|/
* 8ce8dc3 add image verification test
* dde253c add image verification
* 2669563 (init) Initial commit

然后上面这种查看提交历史很少用,个人更倾向于使用“gitk –all”,从哪个里面复制了sha1的id,只需要几位就可以

1
git rebase -i --autosquash  266956349d88785e89e9

会进入到一个编辑界面(这个地方直接给保存退出了,就没代码),之后再查看就是下面这个样子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ git log --oneline --graph --all
* 579eadb (HEAD -> master) refactor(application properties): use jasypt to hidden database username and password
* 6a1f078 add image verification
| * dd74e4f (origin/master, origin/HEAD) refactor(application properties): use jasypt to hidden database username an
| * 440caf5 error need to solve
| * cedc0b9 feat(security): update securtiy
| * f6a8f34 build(properties): add prod properties
| * 0f67f6b 'formate'
| * dea7958 almost down
| * 45ae82a 周六
| * 3707932 add spring security
| | * a4ffb37 (refs/stash) On master: Uncommitted changes before Update at 2019-7-26 9:15
| | |\
| |/ /
| | * 7a42620 index on master: 8ce8dc3 add image verification test
| |/
| * 8ce8dc3 add image verification test
| * dde253c add image verification
|/
* 2669563 (init) Initial commit

然后这个时候发现还有一个commit是不需要的,再来一次rebase

1
git rebase -i --autosquash  266956349d88785e89e901e9efd8f1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pick 6a1f078 add image verification
pick 579eadb refactor(application properties): use jasypt to hidden database username and password

# Rebase 2669563..579eadb onto 2669563 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# 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.
#
#
# Note that empty commits are commented out

后面我把第一行的pick改成了f,然后提示我

1
2
3
$ git rebase --edit-todo
error: cannot 'fixup' without a previous commit
error: unusable todo list: '.git/rebase-merge/git-rebase-todo'

然后我在Stack Overflow上看到了这个问题的答案
Git: “Cannot ‘squash’ without a previous commit” error while rebase
然后使用上面的方法,成功的修改了下面的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
r 6a1f078  refactor(application properties): use jasypt to hidden database username and password add image verification
s 579eadb refactor(application properties): use jasypt to hidden database username and password

# Rebase 2669563..579eadb onto 2669563 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# 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.
#
#
# Note that empty commits are commented out

保存退出之后让我写合并的commit信息,这个时候想的话,如果我加上–autosquash 应该就不需要我自己再写一遍了吧(没试过)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git log --oneline --graph --all
* 04e2ee2 (HEAD -> master) refactor(application properties): use jasypt to hidden database username and password and delete commit log
| * dd74e4f (origin/master, origin/HEAD) refactor(application properties): use jasypt to hidden database username and password
| * 440caf5 error need to solve
| * cedc0b9 feat(security): update securtiy
| * f6a8f34 build(properties): add prod properties
| * 0f67f6b 'formate'
| * dea7958 almost down
| * 45ae82a 周六
| * 3707932 add spring security
| | * a4ffb37 (refs/stash) On master: Uncommitted changes before Update at 2019-7-26 9:15
| | |\
| |/ /
| | * 7a42620 index on master: 8ce8dc3 add image verification test
| |/
| * 8ce8dc3 add image verification test
| * dde253c add image verification
|/
* 2669563 (init) Initial commit

完美的解决了

1
2
3
$ git branch
init
* master

删除init分支之后运行了git status,提示我去git pull 一下,然后就按照git的提示操作了,再然后就提示我

1
2
3
4
5
6
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)

nothing to commit, working tree clean

push之后,发现远端分支和本地分支合并了,转眼一想,我不能让他合并啊,然后就是把头指针指向我pull之前,准备强行push上去,但是一想还是不对啊,我岂不是白搞这么半天还是得强行push吗,虽然强行push之后得到的效果是我所期待的,只有init提交和最后一个提交。但是感觉还是憨批。。。。。。。。。

1
2
$ git reset --hard 04e2ee2c388f
HEAD is now at 04e2ee2 refactor(application properties): use jasypt to hidden database username and password and delete commit log

小结

一顿操作猛如虎,实则彦祖一米五。。。。。。

0%