将本地回购的所有分支重置为与远程相同
Reset all branches of a local repo to be the same as remote
首先这是不同的,因为这是针对所有分支而不是一个。 (我找到的所有那些一次只为一个分支指定这个)
我在一个大约有 20-30 个分支的回购上工作(长话短说我知道我知道的坏习惯)
无论如何,我正在使用 git bfg 清理器删除一些旧的提交,在使用它之后,您需要删除并重新克隆代码或重置每个分支。
我知道如何使用
设置分支
git fetch origin
git reset --hard origin/master
但是有没有一种方法可以用一个命令重置每个分支,或者我必须一次一个分支吗?
我忽略了很多本地文件,我不想处理复制和重写。 (如 IDE 文件、计算机配置文件等...)
First this is different because this is for all branches not one
您可以使用一个脚本来遍历您的分支,然后在每个分支上执行您想要的任何操作:
# Loop on all the desired branches
for ref in $(git branch -a)
do
# ... DO ANYTHING YOU NEED HERE
# You have the $ref which stores the branch name
# ex: remotes/origin/master
done
有没有更好的ans简单解决方案?
是的,只需再次克隆该项目,您将拥有与原始内容相同的内容。
这正是您为每个分支手动执行的操作。
注:
您可以使用此命令一次获取所有数据:
# Fetch all remotes, branches and remove deledted content
git fetch --all --prune
为什么不直接删除所有本地分支,然后每当远程分支被重新签出时,您就会同步?
# BE CAREFUL!!!
# THIS COMMAND WIPES OUT ALL LOCAL BRANCHES
git branch | xargs git branch -D
xargs 针对 stdin 的每一行运行提供的命令,在本例中为 "git branch -D" 针对原始 "git branch" 命令的每一行。
"git branch -D" 命令对于当前分支将失败,但所有其他分支都将被擦除。
或者你可以用运行 "git branch -f" 的 "xargs" 做一些事情来强制将每个本地分支设置到它的远程副本,但我认为上面的 "git branch -D" 方法是最简单的,也是最直接的后果,潜在的危险。
刚刚写了一个 small tool 来做这个。
这个工具的优点:
- 在一个存储库中支持多个遥控器。
- 支持本地和跟踪分支使用不同的名称。
- 没有容易出错的正则表达式parsing/editing。
这是脚本:
#!/bin/bash
ENOENT=2
EEXIST=17
curref=$(git symbolic-ref HEAD 2>&-)
fetch_all() {
git fetch --all
ret=$?
[ "$ret" -eq 0 ] || {
return "$ret"
}
}
hard_reset_all() {
ret=0
while read -r line; do
branch=$(echo "$line" | cut -c 8- | rev | cut -c 8- | rev)
remote=$(git config --local --get "branch.$branch.remote")
upstream=$(git config --local --get "branch.$branch.merge" | cut -c 12-)
if ! git rev-parse --verify --quiet "$remote/$upstream" 1>&- 2>&-; then
ret=$(( $ret | $ENOENT ))
echo "Branch $branch"
echo " skipped: upstream is absent"
continue
fi
if [ -z "$(git log --oneline -1 "$branch...$remote/$upstream")" ]; then
continue
fi
echo "Branch $branch"
echo " $(git log --oneline -1 $branch)"
if [ "refs/heads/$branch" = "$curref" ]; then
git reset --hard "$remote/$upstream" 1>&- 2>&-
else
git update-ref "refs/heads/$branch" "$remote/$upstream" 1>&- 2>&-
fi
echo " -> $(git log --oneline -1 $remote/$upstream)"
done < <(git config --local --name-only --get-regex '^branch.*remote$')
return "$ret"
}
fetch_all
excode=$?
[ "$excode" -eq 0 ] || {
exit "$excode"
}
if output=$(git status --porcelain) && [ -n "$output" ]; then
echo "Skipped: repo is not clean"
exit $EEXIST
fi
hard_reset_all
excode=$?
[ "$excode" -eq 0 ] || {
exit "$excode"
}
您可以使用以下单行(基于):
git branch --format='%(refname:short)' | xargs -i sh -c "git checkout {} && git reset --hard origin/{}"
--format='%(refname:short)'
从 git branch
中删除烦人的 *
-i
允许使用 {}
作为分支 的占位符
警告:我没有经常使用该命令,所以它可能不完全安全,如果你想让它更安全,请参阅that answer。
完全删除目录,然后克隆存储库。
rm -R repodir
git clone https://github.com/repodir/repodir
首先这是不同的,因为这是针对所有分支而不是一个。 (我找到的所有那些一次只为一个分支指定这个)
我在一个大约有 20-30 个分支的回购上工作(长话短说我知道我知道的坏习惯)
无论如何,我正在使用 git bfg 清理器删除一些旧的提交,在使用它之后,您需要删除并重新克隆代码或重置每个分支。
我知道如何使用
设置分支git fetch origin
git reset --hard origin/master
但是有没有一种方法可以用一个命令重置每个分支,或者我必须一次一个分支吗?
我忽略了很多本地文件,我不想处理复制和重写。 (如 IDE 文件、计算机配置文件等...)
First this is different because this is for all branches not one
您可以使用一个脚本来遍历您的分支,然后在每个分支上执行您想要的任何操作:
# Loop on all the desired branches
for ref in $(git branch -a)
do
# ... DO ANYTHING YOU NEED HERE
# You have the $ref which stores the branch name
# ex: remotes/origin/master
done
有没有更好的ans简单解决方案?
是的,只需再次克隆该项目,您将拥有与原始内容相同的内容。
这正是您为每个分支手动执行的操作。
注:
您可以使用此命令一次获取所有数据:
# Fetch all remotes, branches and remove deledted content
git fetch --all --prune
为什么不直接删除所有本地分支,然后每当远程分支被重新签出时,您就会同步?
# BE CAREFUL!!!
# THIS COMMAND WIPES OUT ALL LOCAL BRANCHES
git branch | xargs git branch -D
xargs 针对 stdin 的每一行运行提供的命令,在本例中为 "git branch -D" 针对原始 "git branch" 命令的每一行。
"git branch -D" 命令对于当前分支将失败,但所有其他分支都将被擦除。
或者你可以用运行 "git branch -f" 的 "xargs" 做一些事情来强制将每个本地分支设置到它的远程副本,但我认为上面的 "git branch -D" 方法是最简单的,也是最直接的后果,潜在的危险。
刚刚写了一个 small tool 来做这个。
这个工具的优点:
- 在一个存储库中支持多个遥控器。
- 支持本地和跟踪分支使用不同的名称。
- 没有容易出错的正则表达式parsing/editing。
这是脚本:
#!/bin/bash
ENOENT=2
EEXIST=17
curref=$(git symbolic-ref HEAD 2>&-)
fetch_all() {
git fetch --all
ret=$?
[ "$ret" -eq 0 ] || {
return "$ret"
}
}
hard_reset_all() {
ret=0
while read -r line; do
branch=$(echo "$line" | cut -c 8- | rev | cut -c 8- | rev)
remote=$(git config --local --get "branch.$branch.remote")
upstream=$(git config --local --get "branch.$branch.merge" | cut -c 12-)
if ! git rev-parse --verify --quiet "$remote/$upstream" 1>&- 2>&-; then
ret=$(( $ret | $ENOENT ))
echo "Branch $branch"
echo " skipped: upstream is absent"
continue
fi
if [ -z "$(git log --oneline -1 "$branch...$remote/$upstream")" ]; then
continue
fi
echo "Branch $branch"
echo " $(git log --oneline -1 $branch)"
if [ "refs/heads/$branch" = "$curref" ]; then
git reset --hard "$remote/$upstream" 1>&- 2>&-
else
git update-ref "refs/heads/$branch" "$remote/$upstream" 1>&- 2>&-
fi
echo " -> $(git log --oneline -1 $remote/$upstream)"
done < <(git config --local --name-only --get-regex '^branch.*remote$')
return "$ret"
}
fetch_all
excode=$?
[ "$excode" -eq 0 ] || {
exit "$excode"
}
if output=$(git status --porcelain) && [ -n "$output" ]; then
echo "Skipped: repo is not clean"
exit $EEXIST
fi
hard_reset_all
excode=$?
[ "$excode" -eq 0 ] || {
exit "$excode"
}
您可以使用以下单行(基于
git branch --format='%(refname:short)' | xargs -i sh -c "git checkout {} && git reset --hard origin/{}"
--format='%(refname:short)'
从git branch
中删除烦人的 -i
允许使用{}
作为分支 的占位符
*
警告:我没有经常使用该命令,所以它可能不完全安全,如果你想让它更安全,请参阅that answer。
完全删除目录,然后克隆存储库。
rm -R repodir
git clone https://github.com/repodir/repodir