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

git 临时切换分支

  •  
  •   yujianwjj · 2023-11-15 10:36:33 +08:00 · 15271 次点击
    这是一个创建于 372 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家在开发过程中,遇到需要切换分支的情况,比如需要紧急修复一个线上 bug 。这个时候,是使用 git commit 临时保存本地代码还是使用 git stash 。

    122 条回复    2023-11-17 06:17:16 +08:00
    1  2  
    pota
        1
    pota  
       2023-11-15 10:37:32 +08:00   ❤️ 3
    git stash
    flyqie
        2
    flyqie  
       2023-11-15 10:39:43 +08:00 via Android   ❤️ 1
    为啥要用 git commit 来污染 commit 记录?
    jaredyam
        3
    jaredyam  
       2023-11-15 10:40:29 +08:00   ❤️ 2
    没啥区别吧。自己的 feature 分支直接 commit 就行,写好 message 方便下次 amend 就好。
    Mrun
        4
    Mrun  
       2023-11-15 10:42:27 +08:00   ❤️ 3
    git work-tree ,可以同时开两个分支
    0x19921213
        5
    0x19921213  
       2023-11-15 10:42:39 +08:00
    git stash
    leconio
        6
    leconio  
       2023-11-15 10:44:55 +08:00
    都不对,“紧急修复一个线上 bug” 不是应该从上一个发版 TAG 拉出 bugfix 分支修复吗?你临时上的版本,还要带上最新的 feature ?
    JamesR
        7
    JamesR  
       2023-11-15 10:45:24 +08:00
    @flyqie #2 别推送远端分支就行了,处理完立马 Reset 回来,没有提交记录的,污染不了,个人是这么做的。
    renmu
        8
    renmu  
       2023-11-15 10:46:04 +08:00 via Android
    wip
    kristofer
        9
    kristofer  
       2023-11-15 10:47:04 +08:00
    @leconio 别急,你再仔细读读 哈哈
    marding
        10
    marding  
       2023-11-15 10:47:14 +08:00
    stash
    codeMore
        11
    codeMore  
       2023-11-15 10:49:26 +08:00
    commit 呗,反正最后合并到主分支之前,这个分支的 commit 都是要 rebase 合并成一个的,不打紧,还有,你切临时分支也不能从当前 feature 分支切啊,肯定得从 master 或者线上的 tag 分支切出来临时分支吧。
    alvinbone88
        12
    alvinbone88  
       2023-11-15 10:49:40 +08:00   ❤️ 2
    git worktree
    dif
        13
    dif  
       2023-11-15 10:50:49 +08:00
    git stash
    air8712
        14
    air8712  
       2023-11-15 10:52:28 +08:00   ❤️ 1
    多 clone 一份代码来做这件事
    leconio
        15
    leconio  
       2023-11-15 10:52:51 +08:00 via iPhone   ❤️ 1
    @kristofer 呃,是怎么保存当前的代码。。我错了。stash 所有分支共用的,分支不多可以这么搞; commit 是可以 amend ,提交前决定 amend 还是再来一个 commit ,或者 reset --soft
    enchilada2020
        16
    enchilada2020  
       2023-11-15 10:53:28 +08:00 via Android
    git 真好用(
    xujiahui
        17
    xujiahui  
       2023-11-15 10:54:06 +08:00
    git stash
    AoEiuV020JP
        18
    AoEiuV020JP  
       2023-11-15 10:55:52 +08:00
    @air8712 #14 再 clone 一份的话缓存之类的没了编译就慢了,属于是下策了,
    zjp
        19
    zjp  
       2023-11-15 10:58:13 +08:00 via Android   ❤️ 3
    stash 之后老忘记,因为平时只看分支树。之前是 commit 再 reset 回去
    IDEA 的暂存功能 shelve 更好用些
    huihushijie1996
        20
    huihushijie1996  
       2023-11-15 11:01:13 +08:00   ❤️ 2
    我是先提交了 然后又用 git reset --soft head^来还原
    SenLief
        21
    SenLief  
       2023-11-15 11:04:56 +08:00
    git stash 不就是做这个嘛?
    Tubering
        22
    Tubering  
       2023-11-15 11:05:40 +08:00
    stash 比较多
    不过也有在 stash 里存太久,list 的时候看到都忘了干嘛的
    4ark
        23
    4ark  
       2023-11-15 11:06:57 +08:00
    worktree 才是最优解
    Vegetable
        24
    Vegetable  
       2023-11-15 11:08:34 +08:00   ❤️ 2
    建议是
    git commit -m "wip: 还没做完"
    因为你的 hotfix 要做多久很难说,况且除了 hotfix 还有别的情况需要临时切换工作分支。stash 其实可以实现与 commit 几乎一样的能力,但是我不喜欢再记一套 stash push 之类的命令,我只在确认自己几分钟之后就会 pop 的情况下用 stash 。

    对于 commit 记录,使用 git rebase 可以清理
    vchroc
        25
    vchroc  
       2023-11-15 11:09:19 +08:00
    jetbrains 系 IDEA ,无此问题
    pkoukk
        26
    pkoukk  
       2023-11-15 11:10:54 +08:00
    @flyqie #2 rebase 修一下不就完了
    pkoukk
        27
    pkoukk  
       2023-11-15 11:14:22 +08:00   ❤️ 1
    我用 commit ,不理解为啥用 stash ,这些内容在你要修的线上分支可能会用到么?如果用不到 stash 它干嘛。
    说一个暴论,在当前 git 有 rebase 和 cherry pick 功能以后,stash 没有太大的价值了
    swaggeek
        28
    swaggeek  
       2023-11-15 11:17:10 +08:00
    用 idea 的话,有个 shelve change 的功能
    Leviathann
        29
    Leviathann  
       2023-11-15 11:20:04 +08:00
    @swaggeek 这个和 stash 有什么区别
    28Sv0ngQfIE7Yloe
        30
    28Sv0ngQfIE7Yloe  
       2023-11-15 11:20:44 +08:00
    百分之八十的开发者都用不明白 rebase
    qxooqx
        31
    qxooqx  
       2023-11-15 11:22:38 +08:00 via Android
    @zjp stash 后容易忘记在那个分支上执行 pop ,commit 的话可以在提交记录中快速找到分支并切回去,然后只要取消 commit 就可以了
    TAFMT
        32
    TAFMT  
       2023-11-15 11:23:48 +08:00
    git stash
    Colderer
        33
    Colderer  
       2023-11-15 11:23:50 +08:00   ❤️ 3
    @pkoukk 呵呵,stash 完美贴合这个使用场景;暂存完,切 hotfix 分支,修完 bug ,切回原分支,stash pop ,继续干活
    whosesmile
        34
    whosesmile  
       2023-11-15 11:29:45 +08:00
    1. git stash 后面可以在 pop 回来
    2. git commit 但是不要 push ,后面接着修改后,等到正式提交的时候,可以 git commit --amend
    3. git commit 并且推送到仓库了,后面如果修改后想覆盖前面的提交,只要你能确认这个分支之前的 commit 没有其他人在使用,可以 push --force ,**一定要确认没其他人在使用**
    Rehtt
        35
    Rehtt  
       2023-11-15 11:34:15 +08:00
    @pkoukk 如果这个时候无意间推送远程了,而公司远程仓库又禁用 rebase
    HarryQu
        36
    HarryQu  
       2023-11-15 11:34:36 +08:00   ❤️ 2
    如果是用 IntelliJ IDEA 的 IDE ,我推荐使用 IntelliJ IDEA 的 Shelves Changes 功能,也非常好用。

    Shelves Changes 所实现的功能和 git stash 所实现的功能类似。

    Shelf 的中文意思是书架,复数是 shelves 。但 Shelves Changes 功能是 IntelliJ IDEA IDE 的功能,并不是 Git 命令。
    zhuangpipi
        37
    zhuangpipi  
       2023-11-15 11:35:44 +08:00
    一般有多个 worktree ,直接再开个窗口好
    HarryQu
        38
    HarryQu  
       2023-11-15 11:36:27 +08:00   ❤️ 1
    Shelves Changes ,我以前总结的一片文章,可以参考下: https://www.hi-cat.cn/11953
    ruchee
        39
    ruchee  
       2023-11-15 11:54:29 +08:00   ❤️ 1
    相同的工程代码,常年保持至少三个仓库备用,命名分别叫 repo1 、repo2 、repo3 ,使用时用软链接链过去,比如 ln -s repo1 repo 。

    这样,项目路径就是 repo ,然后临时有别的任务要搞,那就删了原来的软链接,重新链一个别的目录,比如 ln -s repo2 repo 。

    无缝衔接,丝滑得很。
    z1645444
        40
    z1645444  
       2023-11-15 11:54:48 +08:00
    最方便的还是 git stash 来回跑,stash 也是为此而生的,为什么要给 commit 语义施加更多负担,最后还要涉及到 rebase 。
    nagisaushio
        41
    nagisaushio  
       2023-11-15 11:57:46 +08:00 via Android
    前面说 rebase 的,其实可以切回来后直接 reset 那个临时 commit 呀

    我选择 commit 是因为 stash 完有可能会忘了,而 commit 就在历史树里不会忘
    Rache1
        42
    Rache1  
       2023-11-15 11:58:32 +08:00
    @Rehtt #35 就算推了,在自己的 feature 分支,删掉远端分支也不是不行
    enchilada2020
        43
    enchilada2020  
       2023-11-15 12:01:53 +08:00 via Android
    @ruchee 这位更秀。。
    Azone
        44
    Azone  
       2023-11-15 12:05:13 +08:00
    更好的办法是用 git worktree
    vcbal
        45
    vcbal  
       2023-11-15 12:05:19 +08:00
    @leconio 你先看清问题以及回复,感觉你回的莫名其妙
    wjfz
        46
    wjfz  
       2023-11-15 12:07:17 +08:00   ❤️ 1
    开始用 stash ,但有时候 stash 之后会忘掉,而且也不太方便 compare 。
    用 commit 可以在修完 bug 回来之后,git reset HEAD~把临时提交还原回来。还是很舒服的。
    hijoker
        47
    hijoker  
       2023-11-15 12:34:58 +08:00
    @HarryQu 链接好像有问题
    Kirscheis
        48
    Kirscheis  
       2023-11-15 12:41:38 +08:00   ❤️ 1
    我是用 stash ,楼上这么多用 commit 的都没提 hooks ,大家的 commit 上都没有钩子吗。。
    Helsing
        49
    Helsing  
       2023-11-15 12:50:37 +08:00 via iPhone
    git worktree ,想同时开多少个分支就可以开多少个分支
    besto
        50
    besto  
       2023-11-15 13:01:16 +08:00
    @pkoukk stash 还是很有用的,当然不是不可替代,stash 相当于可以把一些 CL 特别放在那,list 一下就能立刻找到,比较相似的是生成 patch 放一边。
    crysislinux
        51
    crysislinux  
       2023-11-15 13:03:17 +08:00   ❤️ 1
    > 楼上这么多用 commit 的都没提 hooks ,大家的 commit 上都没有钩子吗。。

    commit 上搞钩子其实不太好,push 的时候跑干扰少的多

    > git commit 并且推送到仓库了,后面如果修改后想覆盖前面的提交

    推送也是推送自己的 branch ,最后 merge PR 也是 rebase ,你是直接 main 上推么?
    besto
        52
    besto  
       2023-11-15 13:05:10 +08:00
    @Kirscheis 一般 commit hook 都是签名或是对抗 gerrit 写的 泛式的 模板。主要楼主这事情,压根不是事,git 至少有 10+种办法处理,还都很简单,只要本地当前 branch 是 track 远端的,直接换成 detach 状态,把改动提交了,再生成一个本地分支就行了。
    ChevalierLxc
        53
    ChevalierLxc  
       2023-11-15 13:11:20 +08:00
    git commit 后还可以用 git rebase -i HEAD~2 去 merge 两次 commit. 方法很多,多看看吧
    myl0204
        54
    myl0204  
       2023-11-15 13:21:49 +08:00
    stash 和 commit 都能实现目的,不过 stash 的语境更符合一点吧,我记得 git book 上 stash 的翻译是暂存。
    ooee2016
        55
    ooee2016  
       2023-11-15 13:27:29 +08:00
    git stash 更适合, 但是还需要 git stash list 确认下.
    git commit 也行, 完事 rebase 一下,反正是自己本次的分支,也不影响别人
    sprite82
        56
    sprite82  
       2023-11-15 13:43:13 +08:00   ❤️ 4
    用 commit 的基本不是菜就是偷懒,抱着无所谓的态度,污染就污染了,什么后续 rebase 合并提交,绝对不会用的。还什么 stash 会忘记的,找不到的哪些,你自己要做什么还会忘记的? stash 不会备注信息吗?
    都是借口, 我说的可能优点极端,但符合大多数人真实心理
    20015jjw
        57
    20015jjw  
       2023-11-15 14:01:10 +08:00 via iPhone
    commit 啊 commit 最稳妥
    不会 amend rebase reset 吗
    楼上什么不是菜就是偷懒是什么逻辑
    谁告诉你 xommit 完就一定不能改了?
    lovelylain
        58
    lovelylain  
       2023-11-15 14:08:09 +08:00 via Android
    commit 吧。stash 有冲突解决后得单独 drop ,否则一直在然后后面忘了,就不知道有没有合并以及是哪个分支的。
    SmallZheng
        59
    SmallZheng  
       2023-11-15 14:10:34 +08:00
    gwip
    serge001
        60
    serge001  
       2023-11-15 14:14:45 +08:00
    git commit 吧 可以在你自己的临时分支上,完了再切回来 amend 或者 rebase 都行
    Jxnujason
        61
    Jxnujason  
       2023-11-15 14:16:21 +08:00
    习惯用 commit 了,要 push 前 squash 一下
    lisxour
        62
    lisxour  
       2023-11-15 14:23:30 +08:00
    @nagisaushio 会忘那就证明你压根就没好好用 git ,stash 就是专门来干这种事的,然而大部分人基本都只会 git add 、git commit 、git pull 、git push
    Ericcccccccc
        63
    Ericcccccccc  
       2023-11-15 14:26:14 +08:00
    就是 stash
    ColdBird
        64
    ColdBird  
       2023-11-15 14:28:35 +08:00
    我以前都是通过 commit 暂存的,记录 wip 或者暂存,学到了
    whyrookie
        65
    whyrookie  
       2023-11-15 14:33:47 +08:00
    stash
    ichanne
        66
    ichanne  
       2023-11-15 14:34:09 +08:00
    因为经常出现这种情况,我是同一份代码库本地拉了两份,其中一份永远对应线上代码,另一份是开发代码,不需要来回保存代码切分支
    shawndev
        67
    shawndev  
       2023-11-15 14:34:48 +08:00   ❤️ 2
    上策 git worktree
    中策 git stash
    下策 git commit
    Terry166
        68
    Terry166  
       2023-11-15 14:38:21 +08:00
    可以用 git commit ,用 git stash 更简洁一些:

    When you are in the middle of something, your boss comes in and demands that you fix something immediately. Traditionally, you would make a commit to a temporary branch to store your changes away, and return to your original branch to make the emergency fix, like this:

    # ... hack hack hack ...
    $ git switch -c my_wip
    $ git commit -a -m "WIP"
    $ git switch master
    $ edit emergency fix
    $ git commit -a -m "Fix in a hurry"
    $ git switch my_wip
    $ git reset --soft HEAD^
    # ... continue hacking ...

    You can use git stash to simplify the above, like this:

    # ... hack hack hack ...
    $ git stash
    $ edit emergency fix
    $ git commit -a -m "Fix in a hurry"
    $ git stash pop
    # ... continue hacking ...
    MonkeyJon
        69
    MonkeyJon  
       2023-11-15 14:49:24 +08:00
    # 保存当前未 commit 的代码
    git stash

    # 保存当前未 commit 的代码并添加备注
    git stash save "备注的内容"

    # 列出 stash 的所有记录
    git stash list

    # 删除 stash 的所有记录
    git stash clear

    # 应用最近一次的 stash
    git stash apply

    # 应用最近一次的 stash ,随后删除该记录
    git stash pop

    # 删除最近的一次 stash
    git stash drop
    xuxu5112
        70
    xuxu5112  
       2023-11-15 14:52:41 +08:00
    clone 两份互不影响
    liuidetmks
        71
    liuidetmks  
       2023-11-15 15:09:26 +08:00   ❤️ 2
    stash 只适合 10 分钟以内能切回来的情况。


    发现 bug1 stash
    你切换到分支 bugfix1 ,做了一半,发现更紧急 bug2 ,又要 stash
    多来几次,你确定能记住顺序?

    commit + reset 挺好的, 通过少量简单指令的组合,做复杂事情,而不是提供复杂的指令做复杂的事情。
    YienX
        72
    YienX  
       2023-11-15 15:42:36 +08:00
    @MonkeyJon 其实应该先 git add .
    不然新建的文件没有被 stash ,🤣等你改完 bug 发现有一堆新建的文件
    YienX
        73
    YienX  
       2023-11-15 15:43:28 +08:00
    @MonkeyJon 哦看错,以为你在说 整个流程...
    unco020511
        74
    unco020511  
       2023-11-15 15:45:58 +08:00
    我们项目比较大,都是准备几个 project 来切换 workspace 的.正常的话,如果是用 jb 系列的 ide 我更倾向于用 ide 提供的 shelf,如果只用 git 自身的,那就 stash 咯
    AquanllR
        75
    AquanllR  
       2023-11-15 15:48:02 +08:00
    git stash
    296727
        76
    296727  
       2023-11-15 15:58:13 +08:00
    再 clone 一个项目,在那里 fix 最简单
    HangoX
        77
    HangoX  
       2023-11-15 16:01:16 +08:00
    都不是,你应该保留一个专门用来修复的 clone 版本,你操作再逆天,总有失误的时候,线上问题又比较紧急
    出问题就用直接用那个 clone 版本

    实际上我有 5 个项目的 clone 版本,需要的时候直接多开一个即可
    mynameislihua
        78
    mynameislihua  
       2023-11-15 16:04:05 +08:00
    确实,可任意专门再弄一个 clone 版本
    4771314
        79
    4771314  
       2023-11-15 16:12:29 +08:00   ❤️ 1
    commit ,我甚至会 push ,别问我为什么?等你丢过代码就知道了

    自己的分支,后面 rebase 就可以了
    ygtq
        80
    ygtq  
       2023-11-15 16:14:53 +08:00
    @liuidetmks 这个就有点杠了,哪来那么多都是紧急且同一时间的 bug ,如果真的 bug1 非常紧急你在处理,同时 bug2 也来了也紧急,那就喊别人处理,没有别人就排队处理,总有一个优先级,真的都紧急都很复杂需要 debug 很久,你一个人也不可能同时处理两个,都是人,只能“多任务”式的并发处理,没法真正的“多线程”的并发一个以上的事情啊
    jfds
        81
    jfds  
       2023-11-15 16:20:29 +08:00
    我的解决方案是代码 copy 一份多开一个项目
    tlerbao
        82
    tlerbao  
       2023-11-15 16:30:40 +08:00
    @HarryQu #38 链接一片空白
    tlerbao
        83
    tlerbao  
       2023-11-15 16:35:34 +08:00
    68 楼正解了把,除了 worktree ,stash 才是最佳方案把?

    IvanLi127
        84
    IvanLi127  
       2023-11-15 16:41:51 +08:00
    我的选择是:
    小 bug 的话,git stash
    bug 不急的话,先做完现在的然后 git commit 并 push
    大 bug 的话,直接 git commit 一个临时的然后 push 到其他分支上,怕后面 stash 丢东西 QAQ
    QlanQ
        85
    QlanQ  
       2023-11-15 17:03:18 +08:00   ❤️ 1
    对电脑没有安全感,不管是下班还是切分支修 bug ,我会毫不犹豫的 commit push ,我怕电脑炸,stash 经常炸,在多人修改一个项目的情况下,很有可能拉了代码,就没办法 stash pop 了,一点安全感都木有
    commit 多了,可以 rebase
    zhouhu
        86
    zhouhu  
       2023-11-15 17:03:48 +08:00
    @4771314 确实,而且如果是自己的 feature 分支,最好推送到远端。
    Sfilata
        87
    Sfilata  
       2023-11-15 17:08:27 +08:00
    @Tubering #22 stash 可以加消息的,一般只要不是存太多问题都不大。
    pkoukk
        88
    pkoukk  
       2023-11-15 17:21:01 +08:00
    @Colderer #33 但是如果你用 commit 就只需要 commit ,切 hotfix ,修完,切原分支 就行了啊。
    pkoukk
        89
    pkoukk  
       2023-11-15 17:22:51 +08:00
    @Rehtt #35 一般只有 master 和 release 这样的分支是 protected 的,但是这种分支本来就应该禁止直接 commit ,只接受 mr 或者 pr 合并的。
    cyningxu
        90
    cyningxu  
       2023-11-15 17:28:33 +08:00 via Android
    之前一直用 stash ,但发现有时候分支太多比较难对应,现在大概率都是 commit 到本地,回来再 rest soft 。
    pkoukk
        91
    pkoukk  
       2023-11-15 17:31:36 +08:00   ❤️ 4
    @sprite82 #56 一看就没用过 github work flow 或者 gitlab work flow 。
    所有的 bug fix 和 feature 都应该在独立的分支开发,最终通过 mr 或者 pr 合并到 master ,合并的时候默认伴随着 rebase ,就是让你 commit 的时候别有负担。
    写了东西不敢 commit ,不敢推,害怕污染,你要 git 干嘛?磁盘炸了怎么办?
    lbfjkaou
        92
    lbfjkaou  
       2023-11-15 17:33:02 +08:00
    @huihushijie1996 #20 正解
    nunterr
        93
    nunterr  
       2023-11-15 17:33:31 +08:00
    你选择使用 git commit 或 git stash 都可以来处理当前分支上的未完成工作。两者各有优缺点:
    使用 git commit:
    优点:这是一种更“永久性”的保存方式。提交后的更改会被记录在版本历史中,可以在任何时候回退到这个状态。
    缺点:如果你的更改还不够成熟,就可能会污染你的提交历史。你可能需要之后使用 git rebase 来清理提交历史。
    使用 git stash:
    优点:git stash 可以临时保存你的更改,并让你回到一个干净的工作目录。这对于需要快速切换任务的场景非常有用。稍后可以使用 git stash pop 或 git stash apply 来恢复这些更改。
    缺点:Stash 不是一个“正式”的提交,它不会出现在项目的历史中。此外,如果 Stash 列表过长,有时候可能会忘记或弄错需要应用的 Stash 。
    所以,选择哪种方法取决于你的具体需求。如果你认为你的更改已经足够成熟,可以作为一次提交,那么使用 git commit 是个不错的选择。如果你只是想快速切换分支,而且更改还不够稳定,那么 git stash 可能更适合。
    swaggeek
        94
    swaggeek  
       2023-11-15 17:41:59 +08:00
    @Leviathann 跟 stash 差不多,但是 shelves change 会保存删除后的记录,万一删错了还有挽救空间
    linvaux
        95
    linvaux  
       2023-11-15 17:58:07 +08:00
    git stash
    ludage
        96
    ludage  
       2023-11-15 18:49:34 +08:00
    @HarryQu 大佬 连接不对
    HarryQu
        97
    HarryQu  
       2023-11-15 18:52:08 +08:00
    @hijoker 不好意思,忘记开了,现在可以正常访问了,推荐大家体验下 shelves changes ,很好用。
    HarryQu
        98
    HarryQu  
       2023-11-15 18:52:38 +08:00
    @ludage 再试下,现在可以了。
    ludage
        99
    ludage  
       2023-11-15 18:53:04 +08:00
    @ludage 找到了
    thorneLiu
        100
    thorneLiu  
       2023-11-15 20:02:47 +08:00 via Android
    本地怎么搞都行 因为你用的是 git
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1176 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 18:11 · PVG 02:11 · LAX 10:11 · JFK 13:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.