我经常以主分支上的小修复开始我的旅程,最终看起来比最初想象的更复杂。
所以我很容易陷入这种情况:
* Damned I have more stuff to check (HEAD -> master)
* Forgot to fix this as well...
* Oops, fixed that too
* Fixed this
* (origin/master)
此时有人要我快速对主分支进行一些小改动。因此,我需要创建一个feature
/ bugfix
分支并将master
还原为其origin
:
$ git branch --magic bug/foobar
$ git log
* Damned I have more stuff to check (HEAD -> bug/foobar)
* Forgot to fix this as well...
* Oops, fixed that too
* Fixed this
* (master, origin/master)
目前我用这个解决了我的问题:
$ git branch bug/foobar
$ git reset --hard origin/master
$ git checkout bug/foobar
我显然可以为它创建一个别名(尚未测试):
swap-to="!git branch $@ && \
git reset --hard \
\$(git config --get branch.\$(git rev-parse --abbrev-ref HEAD).remote)/\
\$(git rev-parse --abbrev-ref HEAD) && \
git checkout $@"
有更快/更聪明的方法吗?
答案 0 :(得分:2)
您应该可以将主分支签出为新分支
$ git checkout origin/master -b feature/new_featur
上述解决方案虽然有效,但它设置新分支以跟踪主分支。 (我不喜欢)
在我继续之前,我通常没有跟踪。
我看了IntelliJ如何检查新分支,这是如何。
$ git checkout origin/master
在此之后,git会告诉你,你是在一个独立的头上。既然您有一个与origin/master
相同的HEAD,请继续检查该提交是否为新分支。
$ git checkout -b feature/new_feature
DON“T FORGET to git fetch
:)魔术伤口,哈?我希望它有所帮助!
答案 1 :(得分:2)
在这里,您将开始master
,但我们可以选择任何具有上游 U 设置的起始(本地)分支 B 。 (在您的特定情况下,上游是origin/master
。)您开始执行一项您认为快速而简单的任务,现在您已经意识到它毕竟不是那么快捷,所以您希望& #34;将其剥离"到它自己的分支。
然后,我们可能会观察到,我们想要的是保存当前分支的名称,然后改变Git"当前分支"的概念。到新创建的分支,指向当前提交,然后调整已保存的分支以指向已保存的分支的上游。
分支名称只是指向某个提交的标签。 Git在这里是相当明智的:git branch
允许您创建指向任何现有提交的 new 标签,或移动除当前的任何内容分支到任何现有的提交。默认设置是创建指向当前提交的新分支。
棘手的部分是当前分支无法以这种方式移动,原因是当前分支必须与索引和工作树匹配,除了您正在进行的任何活动更改马上。只有一个面向用户("瓷器")命令用于更改Git"当前分支"的概念,即git checkout
。
幸运的是,git checkout
还有-b
(创建新分支)标志,其运行方式与git branch
非常相似:它默认在当前提交时创建新分支。此外,它避免了尽可能多地触摸索引和工作树 - 就像任何其他git checkout
一样 - 所以如果我们在当前提交中创建一个新分支,它永远不必触及索引或工作树所有。结果是它总是成功,并将我们留在新创建的分支上。 (它可以创建一个指向特定提交的新分支,但这也可能失败 - 但我们不需要这个功能,所以我们可以使用它没有的模式&# 39; t失败。好吧,"并没有失败"只要新的分支名称 是新的,至少。)
解决方案仍然需要几行脚本,但我们可以将其编写为一个名为git-spinoff
的小脚本,并将其放在$ PATH中(我会使用$HOME/scripts/git-spinoff
)。我们甚至可以将它作为shell别名函数执行,但我发现脚本通常更好(更容易理解,调试等)。
为了使这个脚本可靠,让我们实际检查我们的必要条件:我们在某个分支上(所以HEAD
不是"分离")并且这个branch有一个上游集。然后我们可以创建我们的新分支并使用git branch -f
重新点,即不使用git reset
- 另一个分支:
#! /bin/sh
#
# git-spinoff: spin the current branch off to a new
# branch. When this succeeds, we are on the new branch.
die() {
echo "fatal: $@" 1>&2
exit 1
}
# check arguments
case $# in
1) newbranch="$1";;
*) echo "usage: git spinoff <newbranch>" 1>&2; exit 1;;
esac
# make sure we are on a branch that has an upstream
branch=$(git symbolic-ref -q --short HEAD) ||
die "existing branch is detached; there's nothing to restore"
upstream=$(git rev-parse -q --verify @{u}) ||
die "existing branch $branch has no upstream: there's nowhere to restore-to"
# now create and check out out the new branch, or quit if we can't
git checkout -b "$newbranch" || exit $?
# last, re-adjust the previous branch (which is no longer the current
# branch since we are on the new one we created) to point to its own
# upstream (if this fails, ignore the failure!)
git branch -f "$branch" "$upstream"
最后一个命令实际上可以改进,因为有一个&#34;管道命令&#34;那就是我们想要的。要使用它,我们必须保留原始分支的完整(refs/heads/
样式)名称,并选择一条消息。此特定消息可能是可改进的,因此只是一个示例:
fullbranch=$(git symbolic-ref -q HEAD) || die ...
branch=${fullbranch#refs/heads/}
... same as before ...
git update-ref -m \
"git spinoff: re-point $branch to ${branch}@{upstream}" \
$fullbranch $upstream
在我们的路径中使用此git-spinoff
脚本,我们现在可以运行git spinoff
。
修改:现在已经过测试,已包含在https://github.com/chris3torek/scripts中(作为https://github.com/chris3torek/scripts/blob/master/git-spinoff)。
答案 2 :(得分:1)
据我所知,只在一个操作中实现这一点的唯一方法就像你说的那样,使用别名,但是为了进行多个操作,我个人预先设置了一个bash函数别名,基本上和别名一样(你在同一个文件中声明它们,但它们看起来更干净,更不易受欢迎。例如:
yourFunction() {
command1
command2
. . .
}
我希望这会有所帮助。