V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
leonlh
V2EX  ›  git

有没有办法一条命令可以快速 rebase?

  •  
  •   leonlh · 2016-04-21 16:52:32 +08:00 · 8094 次点击
    这是一个创建于 3137 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目用 git 做版本管理,同步代码的时候用的是 git pull --rebase 来保证分支的整洁

    然而 rebase 时如果当前有未提交的代码, git 会提示: Cannot rebase: You have unstaged changes.

    所以我的操作流程是这样的:

    1. git stash
    2. git pull --rebase
    3. (有冲突解决冲突,然后 git rebase --continue)
    4. git stash pop stash

    pull 一个代码,竟然要这么多步骤,简直令人发指。。。 考虑过用 alias 写个命令把这几个命令都加进去,但是如果 rebase 的时候出现冲突就跪了 所以 V2 大神有没有好的方案,能够便捷的 rebase 代码...

    48 条回复    2016-04-23 19:15:59 +08:00
    qdzzyb
        1
    qdzzyb  
       2016-04-21 16:55:56 +08:00
    commit 就可以吧 就不用 stash 了
    neoblackcap
        2
    neoblackcap  
       2016-04-21 16:58:27 +08:00   ❤️ 1
    关键就是你拉代码为什么会有这么多冲突?你有冲突当然要人工干预啊。

    我的建议就是多执行 git pull --rebase ,你的代码要多分模块,多提交,多 push

    冲突多没办法的,什么方案都救不了
    leonlh
        3
    leonlh  
    OP
       2016-04-21 17:02:39 +08:00
    @qdzzyb 当两个人互相提供接口的时候,都没有开发完功能,所以不还不能 commit
    leonlh
        4
    leonlh  
    OP
       2016-04-21 17:03:39 +08:00
    @neoblackcap 改相同的地方有时候确实会有冲突...我是想找个有冲突就停止,没冲突就一直走下去的命令写法...
    neoblackcap
        5
    neoblackcap  
       2016-04-21 17:51:48 +08:00
    @leonlh
    两个人互相提供接口?循环引用?
    而且 rebase 本来就是像你说的一样啊,有冲突才会停止啊,只不过是你多了一步缓存你当前还没完成的内容而已。你像一楼说的 commit 就没事了。不要一个 commit 几千行啊, review 的人都要死了
    wittyfox
        6
    wittyfox  
       2016-04-21 17:55:00 +08:00 via Android   ❤️ 1
    麻烦是因为你的工作流 /分支管理不合理。
    leonlh
        7
    leonlh  
    OP
       2016-04-21 18:01:03 +08:00
    @wittyfox
    @neoblackcap
    情况是这样的,代码没写完,不想 commit ,但是又想 pull 一下保证代码不要太旧,这种情况很多见的吧,比如早上来了 pull 下代码。
    我们的确是在 develop 分支上共同开发的,因为确实有需要前后互相提供接口的地方。
    neoblackcap
        8
    neoblackcap  
       2016-04-21 18:06:02 +08:00   ❤️ 1
    @leonlh
    同意 @wittyfox 的话,你们工作流或者分工不合理,要不然怎么会整天出现冲突。
    你这样的目前这样操作是合理的,我是看不到有更少的步骤了,你当然可以写 alias ,但只能减少你命令输入的次数而已,出现冲突还是得人工干预, 也就是说你解决了冲突之后当然要 git rebase --continue ,这个步骤是自动不了的,要不然你不输入 git 怎么知道你解决了冲突了呢?
    kirisetsz
        9
    kirisetsz  
       2016-04-21 18:07:42 +08:00 via Android   ❤️ 2
    kirisetsz
        10
    kirisetsz  
       2016-04-21 18:09:28 +08:00 via Android   ❤️ 1
    并且养成随手 commit 的习惯 (就像 cmd + S 一样)
    反正之后可以 rebase -i 回头整理和修改提交,没必要那么好看
    leonlh
        11
    leonlh  
    OP
       2016-04-21 18:21:45 +08:00
    @neoblackcap 嗯嗯,人工解决冲突确实是必要的,我也只是想找个『没冲突的时候一条命令就过 ,有冲突就停下来人工解决冲突』的办法而已。。
    leonlh
        12
    leonlh  
    OP
       2016-04-21 18:22:13 +08:00
    @kirisetsz 不错的想法,我试试~
    Pastsong
        13
    Pastsong  
       2016-04-21 18:33:02 +08:00
    这样要写 bash 脚本了,当有冲突停下来,没冲突继续执行
    dorentus
        14
    dorentus  
       2016-04-21 20:01:06 +08:00
    有代码没提交的话 merge/rebase 干嘛?

    任何时候都可以 commit 的,反正没 push 到 server 的话本地之后可以随便调整然后再 push 。

    都用 git 了,不敢 commit 是不对的……
    julyclyde
        15
    julyclyde  
       2016-04-21 21:49:28 +08:00
    @kirisetsz 今天我用了 rebase -i 感觉太有用了。只是会产生一些垃圾数据(不在链上的 commit ),心理略不好受……
    kiwi95
        16
    kiwi95  
       2016-04-21 22:22:31 +08:00
    commit 有什么不敢提交的,不 push 不就可以了, commit 不要省着用。。。 commit 不是要开发完某个功能才做的,基本上什么时候都可以做
    owt5008137
        17
    owt5008137  
       2016-04-21 23:14:04 +08:00 via Android
    除非特别情况不要 rebase , git 最大的特色就是分支管理,动不动就 rebase 就完全失去了这个最重要的功能,那还不如回去用 svn 。
    leonlh
        18
    leonlh  
    OP
       2016-04-22 00:31:11 +08:00
    @owt5008137 合作并行开发当然有 rebase 的必要了呀
    msg7086
        19
    msg7086  
       2016-04-22 01:53:48 +08:00
    @owt5008137 git 最大的特色是分支管理,又不是 merge ,为什么不能动不动就 rebase ?
    能频繁 rebase 才能体现出 git 的分支管理特色。
    lightening
        20
    lightening  
       2016-04-22 03:52:22 +08:00
    分布式版本管理的好处就是 commit 和 push 可以分开。所以可以放心大胆的随手 commit 。
    xAx
        21
    xAx  
       2016-04-22 08:29:45 +08:00
    当团队有那么两个 git 用的不熟的人瞎 rebase,整个团队都要疯
    clino
        22
    clino  
       2016-04-22 09:21:27 +08:00
    @owt5008137 看法相反 尽量用 rebase 而不是 merge
    owt5008137
        23
    owt5008137  
       2016-04-22 09:40:07 +08:00 via Android
    @msg7086 分支管理不仅仅是指可以建多个分支,而是在存在多个分支的时候的一整套工作流。多分支之间的 merge 就是最重要的组成部分
    owt5008137
        24
    owt5008137  
       2016-04-22 09:57:08 +08:00 via Android
    @msg7086 @clino
    最简单地就是,如果尽量要 rebase ,为什么不用 svn ?而且 svn 原生就能版本精确到文件,不像 git 得拉取整个仓库,而且 rebase 的过程还巨慢无比(特别是变更多跨版本多的时候)。
    难道仅仅是为了切分支不用换目录?@leonlh 合作开发需要设置多个 remote 的话想用 git 还勉强说得过去,但是也不是非要 rebase 啊。正常的 merge 完全可以。新版的 tortoisegit 为了提高 rebase 的速度,即便你选了 rebase ,在可以的情况也是用 merge 的。

    另外回答下楼主的问题:高版本的(忘了哪个版本开始有的) git 的配置里,可以设置 automerge 和 autostash

    我们这里除了非程序人员不会用 git ,为了让 git 尽量表现得像 svn 才给他们开 rebase ,程序一律走正常工作流,包括对外接入的东西。只是因为很多人已经被 svn 养成了习惯,不懂 git 的概念,导致很容易错误得 merge 才 rebase 的
    clino
        25
    clino  
       2016-04-22 09:59:58 +08:00
    @owt5008137 看了第一句就没兴趣看下去了 svn 不是同一个时代的相比起来功能差多了
    而且我是说尽量用 rebase,但有时候还是会用 merge 特别是有多个 remote 的时候 svn 有这个能耐吗?
    thuai
        26
    thuai  
       2016-04-22 10:08:46 +08:00
    git alias 可以办到,多个 git 命令命一个别名
    msg7086
        27
    msg7086  
       2016-04-22 11:04:18 +08:00   ❤️ 1
    @owt5008137 rebase 和 merge 的用途本来就不同,不管是该 merge 的时候 rebase ,还是该 rebase 的时候 merge ,都不太合适。
    我不知道你是怎么得出「不要 rebase 」这种结论的。
    svn 的分支切换和 git 的分支切换差得太远了,所以我更不知道你怎么得出「为什么不用 svn 」这种结论的。
    至于为了让 git 表现得像 svn 才开 rebase ,我就呵呵了。
    是不是贵司觉得 history 太单调了不好看所以让大家多玩玩 merge 把 history graph 搞复杂点才好啊。
    xAx
        28
    xAx  
       2016-04-22 11:22:45 +08:00
    @msg7086
    history 是单调好还是复杂好,这个要看贵司是要求能从 history 里看出各种变更信息,还是只要能看明白改了什么就行。
    用不用 rebase 是和管理需求有一定联系的。
    ---

    难道各位的团队里就没那么几个傻叉?用个 rebase 害整个团队都要各种调记录的?

    虽然不用 rebase 提交历史不好看一点,但整个团队协作没有风险
    owt5008137
        29
    owt5008137  
       2016-04-22 12:56:47 +08:00 via Android
    赞同 @xAx
    @msg7086 我从来没说不要 rebase ,只是说尽量少用 rebase 。 history graph 里分支多有什么关系? github 上分支多的开源项目多了去了。你看有几个 PR 会用 rebase 的?而且特别是性能问题,只有当你碰上复杂的多端合作开发,测试完成后一次 push 要合并很多 commit ,并且里面包含资源,你才能感受到 rebase 的局限性在哪
    6v
        30
    6v  
       2016-04-22 13:01:11 +08:00
    @leonlh 我一般是 commit 一个临时提交,然后之后开发再 commit --amend 就行。我觉得这样不影响 rebase 的节奏,比 stash 方便一丢丢。
    owt5008137
        31
    owt5008137  
       2016-04-22 13:09:12 +08:00 via Android
    @clino 所以我的回答里已经说了,每次拉取 rebase ,和 svn 相比优势也就剩下多分支了。缺点倒是多得一坨。

    所谓 git 和 svn 的先进性相比,不是因为 git 比 svn 发明得晚,也不是它是 linus 发明的。而是它的工作方式和理念能解决实际的问题,这些实际的问题里,多分支 merge 是个比重比较高的点。只是多个 remote 的话用 svn 也不是很难解决,只是麻烦一点而已。

    现在,其实很多人已经习惯了 svn ,经常容易拿 svn 的模式套在 git 上,导致很难理解这些理念,并且容易误操作。我的理念是,如果这些容易产生的误操作带来的解决问题的时间已经大于用 git 替换 svn 所节省的时间。那何必用 git 。难道只是很多人说 git 先进?先进的 scm 多了去了,和 git 相近的就有 hg ,为什么不用?还有 p4 ,为什么不用?
    clino
        32
    clino  
       2016-04-22 13:35:40 +08:00
    @owt5008137 没发现 git 有你说的那么多缺点 另外我最早先学的 hg,用了好一段时间还不得要领,再学 git 的时候很快就用得很好了,我为什么要用 hg? 何况 git 性能碾压 hg 更不要说 svn 了
    msg7086
        33
    msg7086  
       2016-04-22 13:48:20 +08:00
    @xAx 我司的 Merge 乱的不行,要 Revert 或者 Blame 的时候蛋疼无比。
    不过你说的没错,这主要是团队管理上的需求。

    @owt5008137 GitHub 上 Rebase 上游才是标准做法吧?我倒是很少见到 PR 要 Merge update 的。
    至于你提到 hg 我就觉得更好玩了。
    我觉得 hg 最为人诟病的地方就是开分支有代价而且不能随便 Rebase 。
    我之前维护 hg 版的 x265 mod ,需要自己维护一个补丁串,最后只能在 bitbucket 上开一个 Patch series 项目,每次上游更新了,本地就要弹出所有补丁, update 到 tip ,然后再把补丁一个一个打回去,打出问题了还要被 mq 恶心一通然后去处理合并冲突。然后每一个想 fork 和想贡献代码的人都跑来问我这货到底要怎么用在官方 repo 上,要怎么 fork ,要怎么 pr 。
    我很想知道你用 hg 的时候是怎么解决这些问题的。
    反正我是醉得不行,维护了几个月实在受不了了,老老实实切到他家的 Git 镜像上开分支 Rebase 了。

    最后上一张我司的 History 。三五人的小团队的项目。作为处女座我忍不了 Merge 。然而 YMMV 。
    owt5008137
        34
    owt5008137  
       2016-04-22 14:57:50 +08:00
    @clino 按你们喜欢的方式来吧。本来这些个功能就是针对不同场景提供的。我不建议 rebase 是因为我以前也是默认开 rebase 的,但是碰到好几次一个 commit 要 rebase 好几次,而且 commit 数量稍微多一点就要我等好久,再加上碰到过好几次相同类型的冲突要解决好几次。不甚其烦,自从去掉 rebase 以后天下太平。而且如果不 rebase 首先就没有了 @leonlh 提的这个问题。只是个人建议而已。

    @msg7086 我说的很多人不理解 git 工作流的理念的结果就是你说的很多人“跑来问我这货到底要怎么用”。所以我才说默认开 rebase 是妥协的结果。其他的不想浪费时间争论了,用你喜欢的方式吧,最顺手的才是最高效的。随便贴一个 github 上的项目的图吧。

    clino
        35
    clino  
       2016-04-22 15:08:54 +08:00
    @owt5008137 我们内部用的是 gerrit, 确实有 code review 过程当中又有别人的提交先合入,此时 gerrit 默认的行为是 merge 的,当然如果历史差太多 gerrit 会出 path conflict 错误强制你 rebase, 当然 web 界面上也有 rebase 按钮可以直接 rebase
    在用 gerrit 的情况下习惯 rebase 并不会带来多少负担
    即使在 github 上,如果别人给你提交了 pr,一般你也会希望他 rebase 到最新的上面修改这样比较清楚利于 review 所以我要是给别人提交 pr 我的习惯是一定 rebase 到最新的再提,这样对别人比较友好
    owt5008137
        36
    owt5008137  
       2016-04-22 15:27:51 +08:00
    @clino 我刚刚看了一下是有些项目用 rebase 合并 PR 的,但是自动的是没有 rebase 的。考虑到 code review 的话可能 rebase 的确会让分支看起来简单一些吧。其实比如上面我发的那个图, code review 的时候只看“与第 2 个父节点比较差异”的部分就可以了。因为“与第 1 个父节点比较差异”的内容是之前 review 过的(当然前提是如果每次 merge 都被 review 过)。不过我猜 gerrit 会强制你 rebase 可能是为了减少分支数。
    clino
        37
    clino  
       2016-04-22 15:49:13 +08:00
    @owt5008137 我之前说了 gerrit 默认的方式是 merge 只有新 patch 基于的版本实在太旧才会出 path conflict
    msg7086
        38
    msg7086  
       2016-04-22 20:49:53 +08:00
    @owt5008137
    1. 你这张图里我只看到一个 Merge 。
    2. 冲突要解决很多次所以才选择 Merge 听上去像是为了偷懒而选择 Merge 一样?
    hantsy
        39
    hantsy  
       2016-04-22 23:09:31 +08:00
    rebase 太太痛苦了。。。 conflict 会特别多。

    我们项目只会用 Github Flow ,用 Merge 合并,保留每个 Branch 真实开发 line , rebase 完全将提交重排了。
    hantsy
        40
    hantsy  
       2016-04-22 23:14:03 +08:00
    @clino 其实用 Github , 经常同步 master 到 fork 中的 branch, 几乎不会有冲突产生,如果直接 Git rebase , commit 次数太多的话, 10 次 8 次会产生冲突。
    hantsy
        41
    hantsy  
       2016-04-22 23:15:47 +08:00
    最近看了一下 HG ,不得不说的是 HG 有些方面设计比 GIT 更好一些。
    hantsy
        42
    hantsy  
       2016-04-22 23:17:02 +08:00
    @clino gerrit 没用过, 有 Github 直接在 PR 代码上 Code Review ,太方便了。
    kirisetsz
        43
    kirisetsz  
       2016-04-23 06:29:31 +08:00
    @julyclyde 那是什么?不在链上的 commit ?没遇到过啊…… 你说的是 merge commit 会消失的事情么?
    clino
        44
    clino  
       2016-04-23 07:45:50 +08:00 via Android
    @hantsy 不理解 要是 rebase 有冲突应该 merge 也会才对
    gerrit 在 code review 功能方面比 github 强
    cszchen
        45
    cszchen  
       2016-04-23 09:26:52 +08:00 via iPhone
    看你们撕逼完全插不上嘴,我对 git 不是很熟练。
    请教一下,比如我 master 从其他分支合并稳定可发布的版本,有一天 master 从一个线上 bug 修复分支(hotfix)合并了一个 bug 修复。然后我开发分支(也可能有其他分支)rebase 一下 master ,之后还是用 merge ,这样对吗
    msg7086
        46
    msg7086  
       2016-04-23 10:15:10 +08:00
    @cszchen 我个人习惯是用 Git Flow Simple ,上游更新了本地 Rebase ,完成 Feature 以后 Merge In 。
    至于如果你是 Master 稳定版 Dev 开发版,是不能 Rebase Master 的。
    一种是参考 Git Flow 里 Hotfix 的做法, Fork 出来修好 Bug 以后 Merge 到两边。
    另一种是我们现在在用的, Master 里直接修好以后 Cherry Pick 到 Dev 去。
    faywong8888
        47
    faywong8888  
       2016-04-23 13:57:09 +08:00
    有冲突怪不了版本控制工具,针对你的场景我给个方案:
    >不用版本控制,直接拷贝覆盖。能满足你的需求。
    julyclyde
        48
    julyclyde  
       2016-04-23 19:15:59 +08:00
    @kirisetsz 你看一下 commit 的号码就知道了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5169 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 09:20 · PVG 17:20 · LAX 01:20 · JFK 04:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.