V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
5bb864e1fc775087
V2EX  ›  问与答

git 可以在 B 分支直接推送改动给 A 分支合并, 而不用切换到 A 分支的办法吗?

  •  
  •   5bb864e1fc775087 · 2020-09-05 11:41:22 +08:00 · 5937 次点击
    这是一个创建于 1575 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我现在在 dev 分支,提交了一个 commit,想让 master 合并这几个改动
    我只知道要先切换到 master 分支,然后再 git merge dev 实现合并
    有办法实现不用切换到 master 分支,直接让 master 分支合并这一个 commit 吗?

    这种切换到 master 分支,再 git merge 的方式让我这个强迫症难受:

    1. 切换到 master 分支,git 会把我在 dev 分支里新建的文件都删掉,恢复 master 分支的状态
    2. 然后我再 git merge dev,就又把那些文件创建回来

    如果我在 dev 分支的 commit 里创建了几百个文件,这一来一回就要改动几百*2 的文件,就很不爽

    如果能让 master 分支先合并了,我再切换到 master 分支,这样就不用删这些文件又恢复这些文件

    45 条回复    2021-05-11 17:11:18 +08:00
    blindie
        1
    blindie  
       2020-09-05 11:42:43 +08:00
    可以了解一下 git stash 这个功能
    5bb864e1fc775087
        2
    5bb864e1fc775087  
    OP
       2020-09-05 11:52:29 +08:00
    @blindie #1 git stash 我知道,但不是这个用途吧? git stash 不就是把未提交的文件,找个地方存起来,然后把暂存区清空(应该是叫暂存区吧忘了),事后可以再恢复出来
    5bb864e1fc775087
        3
    5bb864e1fc775087  
    OP
       2020-09-05 11:53:10 +08:00
    @5bb864e1fc775087 #2 git stash 跟我说的东西没关系吧
    silentsee
        4
    silentsee  
       2020-09-05 11:54:19 +08:00
    git stash
    git checkout master
    git merge dev
    git checkout dev
    git stash pop
    TMaize
        5
    TMaize  
       2020-09-05 11:55:36 +08:00 via Android
    我都是项目再复制一份,一个用来合并,一个用来开发
    5bb864e1fc775087
        6
    5bb864e1fc775087  
    OP
       2020-09-05 12:02:31 +08:00
    @silentsee #4 好吧 我帖子没说清楚;我举的例子是我当前在 dev 分支, 已经把改的东西都 git commit 了, 这时执行 git status 显示我没有未提交的改动; 这时我在 dev 分支我要把我刚刚在 dev 分支提交的 commit 合并到 master 分支
    5bb864e1fc775087
        7
    5bb864e1fc775087  
    OP
       2020-09-05 12:04:57 +08:00
    举个例子
    git init // 这时我在 master 分支
    git checkout -b dev
    touch test
    git commit -m "test"
    然后我现在在 dev 分支, 要把刚刚提交的 commit "test" 合并到 master 分支, 但是不想用 git checkout master; git merge dev 这种方式
    lcdtyph
        8
    lcdtyph  
       2020-09-05 12:27:16 +08:00 via iPhone   ❤️ 1
    如果你确定这次 merge 可以 fast forward 的话可以这样

    git branch -f master dev

    但是不建议这么操作
    viggoc
        9
    viggoc  
       2020-09-05 12:38:23 +08:00 via Android
    cherry-pick 了解一下
    sfqtsh
        10
    sfqtsh  
       2020-09-05 12:38:45 +08:00 via Android
    用 worktree 吧
    Kobayashi
        11
    Kobayashi  
       2020-09-05 12:40:10 +08:00 via Android   ❤️ 2
    现在的年轻人怎么都这么懒了? https://stackoverflow.com/q/3216360/5101148
    nicklooo
        12
    nicklooo  
       2020-09-05 12:45:50 +08:00 via iPhone
    @viggoc 我觉得楼主需要的就是这个
    ddsfeng
        13
    ddsfeng  
       2020-09-05 13:03:09 +08:00   ❤️ 1
    @Kobayashi 自己先试一下再讲, stackoverflow 上面最高票的回答.

    里面讲了两种

    第一种:
    git fetch . foo:master

    这条仅限于 master 到 foo 可以 fast-forward

    第二种:
    git fetch <remote> +<remoteBranch>:<localBranch>

    多的这个+号, 如果用了的话, 是强制将 localBranch 的位置更新到 remoteBranch 位置.

    即 如果 master 上有其他的提交, 那么不好意思, 丢了..


    所以就目前来说, 如果存在 master 到 当前分支 需要进行正常合并的, 是没有办法 不切换分支进行 merge 的. (参见那个帖子中, 第二个回复).

    如果可以 fast-forward 过来的, 参见上面第一种方法.
    blindie
        14
    blindie  
       2020-09-05 13:07:50 +08:00 via Android   ❤️ 1
    @5bb864e1fc775087 不管是 github flow 还是 git flow 都不会频繁出现 merge 到 master 的需求。如果使用 gitlab 合作模式走 mr 提交上 master 则可以直接在 gitlab 上提 mr 。况且我看你回答都懂,4 楼回答完全解决你的问题,为什么不写个 shell ?
    newtype0092
        15
    newtype0092  
       2020-09-05 13:11:42 +08:00   ❤️ 1
    如果你分支差异确实这么大,切换起来感觉麻烦的话,重新拉一个仓库长期放在 master 分支就好了,只需合并就 cd 到新仓库的文件夹操作,不用切分支。
    gqbre
        16
    gqbre  
       2020-09-05 13:42:32 +08:00   ❤️ 1
    git rebase dev master
    不要轻易尝试,除非你知道怎么还原
    5bb864e1fc775087
        17
    5bb864e1fc775087  
    OP
       2020-09-05 14:11:53 +08:00
    @blindie #14 4 楼说的就是我主贴里说的,先切到 master 再合并。我平时就是这么做的,只是不爽一来一回删掉文件又恢复回来。所以才来问问有没有不切换到 master 分支的方法
    5bb864e1fc775087
        18
    5bb864e1fc775087  
    OP
       2020-09-05 14:22:13 +08:00
    @viggoc #9 我理解的 cherry-pick 就是把另一个分支的某个 /某些 commit,单独拿到我当前分支再 commit 一遍。如果我没理解错,那我要的情况就不适合,因为执行 cherry pick 前提我要先切换到 master 分支,但是我要的是不切换到 master 分支的方法
    zyfsuzy
        19
    zyfsuzy  
       2020-09-05 14:31:52 +08:00
    cherry-pick 用一下
    silentsee
        20
    silentsee  
       2020-09-05 14:32:57 +08:00
    @5bb864e1fc775087 你是说因为这几百个文件的提交导致切换分支很慢吗?按道理不会太慢的,除非你这几百个文件十分巨大。还是说你就是强迫症,觉得有几百个文件的变动就会让你不爽?
    Mrun
        21
    Mrun  
       2020-09-05 14:41:38 +08:00
    git rebase --onto 看一下
    q8164305
        22
    q8164305  
       2020-09-05 14:43:10 +08:00 via Android
    那你只能 gitclone 两个项目了,一个用来开发,一个用来合并,先把代码推上去,然后另一个项目拉下来合并再推
    5bb864e1fc775087
        23
    5bb864e1fc775087  
    OP
       2020-09-05 15:02:01 +08:00
    @silentsee #20 不是慢,只是强迫症不喜欢这样
    wushigejiajia01
        24
    wushigejiajia01  
       2020-09-05 15:38:30 +08:00   ❤️ 2
    楼上一群人 连帖子都没看明白吗?
    楼主的需求: 将 B 分支合并到 A 分支时, 不需要切换到 A 分支就能直接将 B 分支代码提交给 A 分支

    说实话, 我也觉得这样的操作很麻烦,
    每次在临时分支上写完代码提交 PUSH 完,
    如果需要合并到 DEV, 我都得 [ 先切换到 DEV 分支才能将临时分支的代码合并到 DEV ]

    这种感觉就是 "只能操作当前所在分支, 不可跨分支操作"

    我也想知道有没有什么方法能减少这样的"只能在 A 分支进行'将 B 分支合并到 A 分支的操作'"
    WilliamYang
        25
    WilliamYang  
       2020-09-05 16:26:35 +08:00 via iPhone
    前同事教我的,好像是 git push -u origin dev:master 具体忘记了,就是直接将 dev 推送到 master
    teawithlife
        26
    teawithlife  
       2020-09-05 17:07:22 +08:00
    其实先治疗强迫症才是当务之急[狗头]
    楼主可以先说一下为啥会有一次新增几百个文件的情况吗?
    如果这种情况出现频率很低,那就忍忍用 checkout 吧,或者像楼上几位说的,放两个不同的文件夹
    如果出现概率很高,我感觉 git 不是一个适合的工具
    lsdm999
        27
    lsdm999  
       2020-09-05 17:24:54 +08:00
    1. 这种切换到 master 分支,再 git merge 的方式让我这个强迫症难受
    dev 分支都有可能代码冲突,你能保证跨 master 分支 commit 不出现代码冲突?
    2. 切换到 master 分支,git 会把我在 dev 分支里新建的文件都删掉,恢复 master 分支的状态
    然后我再 git merge dev,就又把那些文件创建回来
    git stash 搞定
    3. 如果我在 dev 分支的 commit 里创建了几百个文件,这一来一回就要改动几百*2 的文件,就很不爽
    git cherry-pick 搞定(如你所描述的,切换分支是最简单不耗时的操作)
    lsdm999
        28
    lsdm999  
       2020-09-05 17:27:24 +08:00
    看错了,2+3:都用 git cherry-pick 即可
    5bb864e1fc775087
        29
    5bb864e1fc775087  
    OP
       2020-09-05 18:11:14 +08:00
    @lsdm999 #27 原本我不认为 git stash 和 cherry-pick 能实现我的需要,但是看到好几个人说,我在想会不会是 git stash 和 cherry-pick 有我不知道的作用。能否按照我 7 楼的例子,接着用 git stash 和 cherry-pick 往下写命令。
    我理解的 cherry-pick 是这样的:要用 cherry-pick 把 dev 分支的 commit 合并到 master 分支,前提要先切换到 master 分支才行,因为 cherry-pick 只能是把其他分支的 commit 转到当前分支。
    lsdm999
        30
    lsdm999  
       2020-09-05 19:00:31 +08:00
    其实 4 楼那个方案已经很接近了。
    git stash
    git checkout master
    git cherry-pick commit-hash 值
    git push
    git checkout dev
    git stash pop
    没有冲突的话整个过程应该挺快的。
    [cherry-pick 这一步有冲突啥的会有提示,可以先 git status 看下状态,那就撤销然后走 merge 手动解决冲突]
    lsdm999
        31
    lsdm999  
       2020-09-05 19:02:01 +08:00
    如果 dev commit 后没有修改,stash 都可以省掉
    5bb864e1fc775087
        32
    5bb864e1fc775087  
    OP
       2020-09-05 19:16:01 +08:00
    @lsdm999 #31 好吧还是我主楼没说清楚。顺着我 7 楼的例子,平时我就是这样:
    git checkout master
    git merge dev // 直接 merge 就行,还不需要 cherry pick
    我发贴的主要目的就是想问能不能不执行 git checkout master,也就是不要切换到 master 分支,且 master 分支能与 dev 分支保持同步
    v2ft
        33
    v2ft  
       2020-09-05 19:33:01 +08:00
    提 merge request 吧,哈哈
    Auster
        34
    Auster  
       2020-09-05 19:34:01 +08:00 via iPhone
    cherry pick 不就是为这种情况的吗
    EminemW
        35
    EminemW  
       2020-09-05 19:59:09 +08:00
    我用 idea 可以直接推到 Master 分支啊。。
    guanhui07
        36
    guanhui07  
       2020-09-05 20:40:03 +08:00
    git stash
    ooops
        37
    ooops  
       2020-09-05 22:06:26 +08:00
    首先,merge,rebase,cherry-pick 之类的操作会产生新的 commit,这就意味着有可能会出现 conflict 。所以不先切到那个分支是不可能实现的。
    其次,好多楼层都说 cherry-pick 好像忽略了它只能把当前分支 cherry-pick
    最后,新增的文件也可以先 git add,再 git stash 。如果强迫症不想在 stage area,可以 pop 之后 reset 那些新增的文件,重回 untrack 的状态。
    yaerda
        38
    yaerda  
       2020-09-05 23:21:54 +08:00   ❤️ 2
    正好分享个最近学到的:git worktree - Manage multiple working trees

    对于你这个问题:
    假如你的项目本地克隆地址是:/path/repo,
    在这个项目里使用命令 git worktree add /path/repo-m master,就可以创建出一个新的文件夹 /path/repo-m,对应于 master 分支,新的文件夹只是原项目 master 分支的一个引用,不用担心占 2 份项目空间
    .
    ..
    /path/repo ---dev 分支
    /path/repo-m ---master 分支

    假使你一般都在 /path/repo dev 分支开发,开发完后,直接新开个命令窗口定位到 /path/repo-m,
    在在 path/repo-m 下轻轻松松便可以 merge 或者 cherry-pick dev 分支的东西,
    方便的实现同一时间本地有多个分支并存,再也不需要 各个常用分支来回切,不断的 stash pop

    以上是个人的一些粗浅理解和使用,如有不对或表达有误,还请指出
    wangyzj
        39
    wangyzj  
       2020-09-05 23:47:16 +08:00
    rebase
    nicklooo
        40
    nicklooo  
       2020-09-06 00:03:07 +08:00 via iPhone   ❤️ 1
    @ooops git stash save -u
    yuriko
        41
    yuriko  
       2020-09-06 11:09:14 +08:00
    git 命令基本都是针对当前分支的操作,涉及到操作空间的逻辑,这个设计我觉得很合理

    以及本地切换 git branch 很麻烦我理解,但关注点是文件的创建流程就是强迫症了,不然你要不要考虑下 gitlog 里的东西都怎么存的?
    SergeGao
        42
    SergeGao  
       2020-09-06 11:18:45 +08:00   ❤️ 1
    楼上都不读题的吗....题主是想在不切回 master 分支的情况下合并某分支到 master 上,说个我知道的操作:

    git fetch origin branch-dev:master

    这个命令的意思就是拉取 branch-dev 分支并合并到 master 分支,所以题主可以先 push 一下 dev 分支,然后执行下上面操作即可
    xi_lin
        43
    xi_lin  
       2020-09-06 13:43:18 +08:00
    @yaerda git worktree 学到了,感谢。不知道为啥我在 v2 上没有点感谢的入口了。。
    standin000
        44
    standin000  
       2020-09-07 09:20:52 +08:00   ❤️ 1
    正想提 worktree,需要 git 2.15 版本,一个目录存在多个分支,公用.git 目录
    James369
        45
    James369  
       2021-05-11 17:11:18 +08:00
    太棒了,我正好有这个需求。因为我经常在切换分支的时候,文件就莫名其妙的丢失了(可能被 ignore 了)。现在可以不用切换直接合并了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2715 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 14:43 · PVG 22:43 · LAX 06:43 · JFK 09:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.