简体   繁体   English

Git:从主分支移动更改

[英]Git: move changes off of master branch

Basic question but this happens to me all the time: 基本问题,但这一直发生在我身上:

  • Make changes in a working-branch working-branch更改
  • Switch to master 切换到master
  • git merge working-branch
  • git push
  • cap deploy (to staging) cap deploy (到staging)
  • make a new cup of tea 泡一杯新茶

then I come back and think of something else and start making some changes...while still on master. 然后我回过头来想想别的东西,然后开始做一些改变......同时还要掌握。

What's an easy way to either: 什么是简单的方法:

  1. prevent direct edits on master (warning perhaps) 防止对master进行直接编辑(也许警告)
  2. to move all edits over to working-branch and clear master so I can continue editing on working-branch 将所有编辑移动到working-branch和清除master以便我可以继续编辑working-branch
  3. to spin edits into an entirely new branch new-working-branch and then discard working-branch ? 将编辑旋转到一个全新的分支new-working-branch ,然后丢弃working-branch

Took a risk and tried recommendation in the latter part of "Branches" section of this page but that just wiped out ALL my edits!?! 本页 “分支”部分的后半部分冒了一个风险并尝试了推荐,但这只是消除了我的所有编辑!?! perhaps because after git branch dubious-experiment and git checkout master the git status on both branches was identical (not 'clean' on master). 也许是因为在git branch dubious-experimentgit checkout master ,两个分支上的git status是相同的(在master上不是'clean')。 So git reset --hard <SHA1sum> wiped out all changes on both!?! 所以git reset --hard <SHA1sum>消灭了两者的所有变化!?!

  git branch dubious-experiment

  M---N-----O----P---Q ("master" and "dubious-experiment")

  git checkout master

  # Be careful with this next command: make sure "git status" is
  # clean, you're definitely on "master" and the
  # "dubious-experiment" branch has the commits you were working
  # on first...

  git reset --hard <SHA1sum of commit N>

From your description, I assume that you did not commit any changes yet – is that correct? 根据您的描述,我假设您尚未提交任何更改 - 这是正确的吗?

If yes, here's your answers: 如果是的话,这是你的答案:

How to prevent direct edits to master 如何防止直接编辑掌握

You would need to set that in your editor, but that will probably be difficult. 您需要在编辑器中设置它,但这可能很难。 Displaying your current branch in your prompt and your editor helps a lot. 在提示符和编辑器中显示当前分支有很大帮助。

How to move the changes into a new branch new-working-branch and then discard working-branch 如何将更改移动到新的分支new-working-branch ,然后丢弃working-branch

git checkout -b new-working-branch
git add …
git commit -m "mycommit" 

As you didn't commit anything to master yet, you don't need to change anything on master. 由于你还没有提交任何东西,你不需要在master上做任何改变。 You can now discard your working-branch if you feel like it. 如果您愿意,现在可以丢弃您的工作分支。

How to move the changes over to working-branch 如何将更改移动到working-branch

git checkout -b temp-branch
git add …
git commit -m "mycommit" 
git rebase --onto working-branch master
git checkout working-branch
git reset --hard temp-branch
git branch -d temp-branch

If your changes don't conflict with any changes that are on master, but not in working-branch, this can be done a lot simpler: 如果您的更改不与master上的任何更改冲突,但不会与工作分支中的更改冲突,则可以更简单地完成此操作:

git stash
git checkout working-branch
git stash pop

If you already committed your changes to master but didn't push to anywhere... 如果您已将更改提交给master但没有推送到任何地方......

create a new branch for the last changes 为最后的更改创建一个新分支

git checkout -b newfeat master

replay all the changes (move the commits) on top of your working-branch branch working-branch分支上重放所有更改(移动提交)

git rebase --onto working-branch origin/master newfeat

change to master branch and reset it to the state of the last push 更改master分支并将其重置为上次推送的状态

git checkout master
git reset --hard origin/master

At this point you have: 此时你有:

  • master pointing to the last pushed commit ( origin/master ) master指向最后被推提交( origin/master
  • working-branch never changed working-branch从未改变过
  • a new newfeat branch that contains all the new commits and is ahead of working-branch . 一个新的newfeat分支,包含所有新的提交,并且领先于working-branch

I used for similar cases: 我用过类似的情况:

git branch -f <branch-name>
git checkout <branch-name>

or 要么

git checkout -B <branch-name>

.

Both variants move the branch branch-name to your current commit with out reseting-hard your tree. 两种变体都将分支branch-name移动到您当前的提交,而不需要重新设置树。

I generally recommend the following Git setting: 我通常建议使用以下Git设置:

git config push.default nothing

With this, you will at least have to name the branch when you push. 有了这个,你至少必须在推动时命名分支。 It won't stop you from committing to master locally, but when you realize you have, you can move those commits to a branch without affecting anyone else. 它不会阻止你在本地提交master,但是当你意识到你拥有时,你可以将这些提交移动到一个分支而不会影响其他任何人。

Get in the habit of typing $ git status before you actually do a git command that will modify something. 在你真正执行一个可以修改某些东西的git命令之前,养成输入$ git status的习惯。

Given that, you have probably edited your file but not checked it in, because you would run git status before the commit. 鉴于此,您可能已经编辑了文件但未将其签入,因为您将在提交之前运行git status In this case, git does the right thing if you just switch branches, then commit. 在这种情况下,如果你只是切换分支然后提交,git会做正确的事情。

If you have fired a commit off to master, then just move the file between branches with something like this: 如果你已经向master发送了一个提交,那么只需在分支之间移动文件,如下所示:

 $ git checkout --patch master <somefile>

You don't really have to reset master if you are just going to merge the same file with it, but since presumably you haven't pushed anything yet you should just reset to your remote tracking branches... 如果你只是想用它合并同一个文件,你真的不需要重置master,但是因为你可能还没有推送任何东西,你应该重置到远程跟踪分支......

$ git reset master origin/master
$ git reset stage origin/stage # whatever

1. prevent direct edits on master (warning perhaps) 1.阻止对主人的直接编辑(也许警告)

You're not the only one to want this. 你并不是唯一一个想要这个的人。 The best idea I've come across is to put the git branch directly in your shell prompt. 我遇到的最好的想法是将git分支直接放在shell提示符中。 My prompt looks like this: 我的提示如下:

[user@host directory:git_branch]

I also color the git_branch entry, so it's quite obvious what I'm working on at all times. 我也为git_branch条目着色,所以我在任何时候都在努力。 These two links on Stack Overflow should help with your prompt. Stack Overflow上的 两个链接应该有助于您的提示。

2. to move all edits over to working-branch and clear master so I can continue editing on working-branch 2.将所有编辑移动到工作分支和清除主控,以便我可以继续编辑工作分支

or 要么

3. to spin edits into an entirely new branch new-working-branch and then discard working-branch? 3.将编辑旋转到一个全新的分支新工作分支,然后丢弃工作分支?

These are really the same question - how to move changes off of master onto a branch, whether it's an old branch or a new branch. 这些都是同样的问题 - 如何将主变更移到分支上,无论是旧分支还是新分支。 And your own answer is correct. 而你自己的答案是正确的。 Although at second glance, assuming you're on master, you could more simply run: 虽然乍一看,假设你是主人,你可以更简单地运行:

git branch new_branch
git reset --hard origin/master

I prefer to just reset master to origin/master rather than worry about a specific commit SHA. 我更喜欢将master重置为origin / master而不是担心特定的提交SHA。 But your steps were essentially correct. 但你的步骤基本上是正确的。 As to why you lost changes, I'd have to think that by mistake there wasn't a branch pointer to Q when you reset master. 至于为什么你丢失了更改,我必须认为在重置master时错误地没有指向Q的分支指针。 No other explanation makes sense. 没有其他解释是有道理的。 Again, having the branch shell prompt will help avoid these mistakes. 再次,拥有分支shell提示符将有助于避免这些错误。 Further more, I'm a big fan of using gitk or git log --graph to verify where my branches are before I move them around. 此外,我很喜欢使用gitk或git log --graph来验证我的分支在我移动它们之前的位置。 Since I can't easily use gitk at work, I have an alias in my .gitconfig called "graph," which is essentially a command-line version of it: 由于我无法在工作中轻松使用gitk,因此我的.gitconfig中有一个名为“graph”的别名,它本质上是它的命令行版本:

[alias]
    graph = log --graph --all --date=short --pretty=format':%C(yellow)%h%Cblue%d%Creset %s %Cgreen %aN, %ad%Creset'

This will show the graph on the far left, the commit SHA in yellow, the branches in blue, the commit message in white, and the author & date in green. 这将显示最左侧的图形,黄色的提交SHA,蓝色的分支,白色的提交消息和绿色的作者和日期。 Of course this can be modified to your own liking. 当然,这可以根据自己的喜好进行修改。

[edited to make the above commands simpler] [编辑使上述命令更简单]

============================== ==============================

In response to the comment below: 回应以下评论:

Start with 从...开始

A-B < origin/master
   \
    C-D < master

Now perform git checkout -b new_branch 现在执行git checkout -b new_branch

A-B < origin/master
   \
    C-D < master, new_branch

Now checkout master, git checkout master . 现在checkout master, git checkout master Note that git checkout -b new_branch && git checkout master is the same as git branch new_branch if you were already on master. 请注意,如果您已经在master上,那么git checkout -b new_branch && git checkout mastergit branch new_branch相同。 I edited the above answer to reflect this. 我编辑了上面的答案以反映这一点。

Now reset master to origin/master, git reset --hard origin/master 现在将master重置为origin / master, git reset --hard origin/master

A-B < master, origin/master
   \
    C-D < new_branch

Because you had a branch (new_branch) pointing at D, no changes are lost. 因为你有一个指向D的分支(new_branch),所以不会丢失任何更改。 If I've made a mistake, please elaborate where. 如果我犯了错误,请详细说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM