重新安置分支机构,包括其所有子级

我有以下Git存储库拓扑:


A-B-F (master)

   \   D (feature-a)

    \ /

     C (feature)

      \

       E (feature-b)

通过重新feature分支,我希望重新构建整个子树(包括子分支):


$ git rebase feature master


A-B-F (master)

     \   D (feature-a)

      \ /

       C (feature)

        \

         E (feature-b)

但是,这是实际结果:


      C' (feature)

     /

A-B-F (master)

   \   D (feature-a)

    \ /

     C

      \

       E (feature-b)

我知道我可以通过执行以下操作轻松地手动修复它:


$ git rebase --onto feature C feature-a

$ git rebase --onto feature C feature-b

但是,有没有一种方法可以自动为分支(包括其所有子代/后代)建立基础?


肥皂起泡泡
浏览 501回答 3
3回答

红颜莎娜

几年前,我写了一些东西来处理这种事情。(当然,欢迎提出改进意见,但不要过多地评判-这是很久以前的事了!我什至还不了解Perl!)它用于更多静态情况-您可以通过设置表单的config参数来配置它branch.<branch>.autorebaseparent。它不会碰到任何没有设置配置参数的分支。如果这不是您想要的,则可以轻松地将其入侵到所需位置。在过去的一两年中,我并没有真正使用过它,但是当我使用它时,它似乎总是非常安全和稳定的,因为大规模自动重新定级是可能的。就是这样 通过保存成一个名为使用它git-auto-rebase在你的PATH。-n尝试使用空运行()选项也是一个好主意。它可能比您真正想要的要详细一些,但是它将向您显示将要尝试重新建立基础的内容以及要建立的内容。可能会节省您一些悲伤。#!/bin/bashCACHE_DIR=.git/auto-rebaseTODO=$CACHE_DIR/todoTODO_BACKUP=$CACHE_DIR/todo.backupCOMPLETED=$CACHE_DIR/completedORIGINAL_BRANCH=$CACHE_DIR/original_branchREF_NAMESPACE=refs/pre-auto-rebaseprint_help() {&nbsp; &nbsp; echo "Usage:&nbsp; git auto-rebase [opts]"&nbsp; &nbsp; echo "Options:"&nbsp; &nbsp; echo "&nbsp; &nbsp; -n&nbsp; &nbsp;dry run"&nbsp; &nbsp; echo "&nbsp; &nbsp; -c&nbsp; &nbsp;continue previous auto-rebase"&nbsp; &nbsp; echo "&nbsp; &nbsp; -a&nbsp; &nbsp;abort previous auto-rebase"&nbsp; &nbsp; echo "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(leaves completed rebases intact)"}cleanup_autorebase() {&nbsp; &nbsp; rm -rf $CACHE_DIR&nbsp; &nbsp; if [ -n "$dry_run" ]; then&nbsp; &nbsp; &nbsp; &nbsp; # The dry run should do nothing here. It doesn't create refs, and won't&nbsp; &nbsp; &nbsp; &nbsp; # run unless auto-rebase is empty. Leave this here to catch programming&nbsp; &nbsp; &nbsp; &nbsp; # errors, and for possible future -f option.&nbsp; &nbsp; &nbsp; &nbsp; git for-each-ref --format="%(refname)" $REF_NAMESPACE |&nbsp; &nbsp; &nbsp; &nbsp; while read ref; do&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo git update-ref -d $ref&nbsp; &nbsp; &nbsp; &nbsp; done&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; git for-each-ref --format="%(refname)" $REF_NAMESPACE |&nbsp; &nbsp; &nbsp; &nbsp; while read ref; do&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; git update-ref -d $ref&nbsp; &nbsp; &nbsp; &nbsp; done&nbsp; &nbsp; fi}# Get the rebase relationships from branch.*.autorebaseparentget_config_relationships() {&nbsp; &nbsp; mkdir -p .git/auto-rebase&nbsp; &nbsp; # We cannot simply read the indicated parents and blindly follow their&nbsp; &nbsp; # instructions; they must form a directed acyclic graph (like git!) which&nbsp; &nbsp; # furthermore has no sources with two sinks (i.e. a branch may not be&nbsp; &nbsp; # rebased onto two others).&nbsp; &nbsp; #&nbsp;&nbsp; &nbsp; # The awk script checks for cycles and double-parents, then sorts first by&nbsp; &nbsp; # depth of hierarchy (how many parents it takes to get to a top-level&nbsp; &nbsp; # parent), then by parent name. This means that all rebasing onto a given&nbsp; &nbsp; # parent happens in a row - convenient for removal of cached refs.&nbsp; &nbsp; IFS=$'\n'&nbsp; &nbsp; git config --get-regexp 'branch\..+\.autorebaseparent' | \&nbsp; &nbsp; awk '{&nbsp; &nbsp; &nbsp; &nbsp; child=$1&nbsp; &nbsp; &nbsp; &nbsp; sub("^branch[.]","",child)&nbsp; &nbsp; &nbsp; &nbsp; sub("[.]autorebaseparent$","",child)&nbsp; &nbsp; &nbsp; &nbsp; if (parent[child] != 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "Error: branch "child" has more than one parent specified."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error=1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; parent[child]=$2&nbsp; &nbsp; }&nbsp; &nbsp; END {&nbsp; &nbsp; &nbsp; &nbsp; if ( error != 0 )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit error&nbsp; &nbsp; &nbsp; &nbsp; # check for cycles&nbsp; &nbsp; &nbsp; &nbsp; for (child in parent) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete cache&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; depth=0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache[child]=1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cur=child&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while ( parent[cur] != 0 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; depth++&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cur=parent[cur]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( cache[cur] != 0 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "Error: cycle in branch."child".autorebaseparent hierarchy detected"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache[cur]=1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; depths[child]=depth" "parent[child]" "child&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; n=asort(depths, children)&nbsp; &nbsp; &nbsp; &nbsp; for (i=1; i<=n; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sub(".* ","",children[i])&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; for (i=1; i<=n; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (parent[children[i]] != 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print parent[children[i]],children[i]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }' > $TODO&nbsp; &nbsp; # Check for any errors. If the awk script's good, this should really check&nbsp; &nbsp; # exit codes.&nbsp; &nbsp; if grep -q '^Error:' $TODO; then&nbsp; &nbsp; &nbsp; &nbsp; cat $TODO&nbsp; &nbsp; &nbsp; &nbsp; rm -rf $CACHE_DIR&nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; fi&nbsp; &nbsp; cp $TODO $TODO_BACKUP}# Get relationships from config, or if continuing, verify validity of cacheget_relationships() {&nbsp; &nbsp; if [ -n "$continue" ]; then&nbsp; &nbsp; &nbsp; &nbsp; if [ ! -d $CACHE_DIR ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: You requested to continue a previous auto-rebase, but"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "$CACHE_DIR does not exist."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; if [ -f $TODO -a -f $TODO_BACKUP -a -f $ORIGINAL_BRANCH ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ! cat $COMPLETED $TODO | diff - $TODO_BACKUP; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: You requested to continue a previous auto-rebase, but the cache appears"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "to be invalid (completed rebases + todo rebases != planned rebases)."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "You may attempt to manually continue from what is stored in $CACHE_DIR"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "or remove it with \"git auto-rebase -a\""&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: You requested to continue a previous auto-rebase, but some cached files"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "are missing."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "You may attempt to manually continue from what is stored in $CACHE_DIR"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "or remove it with \"git auto-rebase -a\""&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; elif [ -d $CACHE_DIR ]; then&nbsp; &nbsp; &nbsp; &nbsp; echo "A previous auto-rebase appears to have been left unfinished."&nbsp; &nbsp; &nbsp; &nbsp; echo "Either continue it with \"git auto-rebase -c\" or remove the cache with"&nbsp; &nbsp; &nbsp; &nbsp; echo "\"git auto-rebase -a\""&nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; get_config_relationships&nbsp; &nbsp; fi}# Verify that desired branches exist, and pre-refs do not.check_ref_existence() {&nbsp; &nbsp; local parent child&nbsp; &nbsp; for pair in "${pairs[@]}"; do&nbsp; &nbsp; &nbsp; &nbsp; parent="${pair% *}"&nbsp; &nbsp; &nbsp; &nbsp; if ! git show-ref -q --verify "refs/heads/$parent" > /dev/null ; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ! git show-ref -q --verify "refs/remotes/$parent" > /dev/null; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; child="${pair#* }"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: specified parent branch $parent of branch $child does not exist"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; if [ -z "$continue" ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if git show-ref -q --verify "$REF_NAMESPACE/$parent" > /dev/null; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: ref $REF_NAMESPACE/$parent already exists"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Most likely a previous git-auto-rebase did not complete; if you have fixed all"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "necessary rebases, you may try again after removing it with:"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "git update-ref -d $REF_NAMESPACE/$parent"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ! git show-ref -q --verify "$REF_NAMESPACE/$parent" > /dev/null; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: You requested to continue a previous auto-rebase, but the required"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "cached ref $REF_NAMESPACE/$parent is missing."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "You may attempt to manually continue from the contents of $CACHE_DIR"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "and whatever refs in refs/$REF_NAMESPACE still exist, or abort the previous"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "auto-rebase with \"git auto-rebase -a\""&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; done}# Create the pre-refs, storing original position of rebased parentscreate_pre_refs() {&nbsp; &nbsp; local parent prev_parent&nbsp; &nbsp; for pair in "${pairs[@]}"; do&nbsp; &nbsp; &nbsp; &nbsp; parent="${pair% *}"&nbsp; &nbsp; &nbsp; &nbsp; if [ "$prev_parent" != "$parent" ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ -n "$dry_run" ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo git update-ref "$REF_NAMESPACE/$parent" "$parent" \"\"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ! git update-ref "$REF_NAMESPACE/$parent" "$parent" ""; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: cannot create ref $REF_NAMESPACE/$parent"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; prev_parent="$parent"&nbsp; &nbsp; done}# Perform the rebases, updating todo/completed as we goperform_rebases() {&nbsp; &nbsp; local prev_parent parent child&nbsp; &nbsp; for pair in "${pairs[@]}"; do&nbsp; &nbsp; &nbsp; &nbsp; parent="${pair% *}"&nbsp; &nbsp; &nbsp; &nbsp; child="${pair#* }"&nbsp; &nbsp; &nbsp; &nbsp; # We do this *before* rebasing, assuming most likely any failures will be&nbsp; &nbsp; &nbsp; &nbsp; # fixed with rebase --continue, and therefore should not be attempted again&nbsp; &nbsp; &nbsp; &nbsp; head -n 1 $TODO >> $COMPLETED&nbsp; &nbsp; &nbsp; &nbsp; sed -i '1d' $TODO&nbsp; &nbsp; &nbsp; &nbsp; if [ -n "$dry_run" ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo git rebase --onto "$parent" "$REF_NAMESPACE/$parent" "$child"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Successfully rebased $child onto $parent"&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo git rebase --onto "$parent" "$REF_NAMESPACE/$parent" "$child"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( git merge-ff -q "$child" "$parent" 2> /dev/null && echo "Fast-forwarded $child to $parent." ) || \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; git rebase --onto "$parent" "$REF_NAMESPACE/$parent" "$child"; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Successfully rebased $child onto $parent"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error rebasing $child onto $parent."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo 'You should either fix it (end with git rebase --continue) or abort it, then use'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo '"git auto-rebase -c" to continue. You may also use "git auto-rebase -a" to'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo 'abort the auto-rebase. Note that this will not undo already-completed rebases.'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; prev_parent="$parent"&nbsp; &nbsp; done}rebase_all_intelligent() {&nbsp; &nbsp; if ! git rev-parse --show-git-dir &> /dev/null; then&nbsp; &nbsp; &nbsp; &nbsp; echo "Error: git-auto-rebase must be run from inside a git repository"&nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; fi&nbsp; &nbsp; SUBDIRECTORY_OK=1&nbsp; &nbsp; . "$(git --exec-path | sed 's/:/\n/' | grep -m 1 git-core)"/git-sh-setup&nbsp; &nbsp; cd_to_toplevel&nbsp; &nbsp; # Figure out what we need to do (continue, or read from config)&nbsp; &nbsp; get_relationships&nbsp; &nbsp; # Read the resulting todo list&nbsp; &nbsp; OLDIFS="$IFS"&nbsp; &nbsp; IFS=$'\n'&nbsp; &nbsp; pairs=($(cat $TODO))&nbsp; &nbsp; IFS="$OLDIFS"&nbsp; &nbsp; # Store the original branch&nbsp; &nbsp; if [ -z "$continue" ]; then&nbsp; &nbsp; &nbsp; &nbsp; git symbolic-ref HEAD | sed 's@refs/heads/@@' > $ORIGINAL_BRANCH&nbsp; &nbsp; fi&nbsp; &nbsp; check_ref_existence&nbsp; &nbsp; # These three depend on the pairs array&nbsp; &nbsp; if [ -z "$continue" ]; then&nbsp; &nbsp; &nbsp; &nbsp; create_pre_refs&nbsp; &nbsp; fi&nbsp; &nbsp; perform_rebases&nbsp; &nbsp; echo "Returning to original branch"&nbsp; &nbsp; if [ -n "$dry_run" ]; then&nbsp; &nbsp; &nbsp; &nbsp; echo git checkout $(cat $ORIGINAL_BRANCH)&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; git checkout $(cat $ORIGINAL_BRANCH) > /dev/null&nbsp; &nbsp; fi&nbsp; &nbsp; if diff -q $COMPLETED $TODO_BACKUP ; then&nbsp; &nbsp; &nbsp; &nbsp; if [ "$(wc -l $TODO | cut -d" " -f1)" -eq 0 ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanup_autorebase&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Auto-rebase complete"&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Error: todo-rebases not empty, but completed and planned rebases match."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "This should not be possible, unless you hand-edited a cached file."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "Examine $TODO, $TODO_BACKUP, and $COMPLETED to determine what went wrong."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; echo "Error: completed rebases don't match planned rebases."&nbsp; &nbsp; &nbsp; &nbsp; echo "Examine $TODO_BACKUP and $COMPLETED to determine what went wrong."&nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; fi}while getopts "nca" opt; do&nbsp; &nbsp; case $opt in&nbsp; &nbsp; &nbsp; &nbsp; n ) dry_run=1;;&nbsp; &nbsp; &nbsp; &nbsp; c ) continue=1;;&nbsp; &nbsp; &nbsp; &nbsp; a ) abort=1;;&nbsp; &nbsp; &nbsp; &nbsp; * )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo "git-auto-rebase is too dangerous to run with invalid options; exiting"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print_help&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; esacdoneshift $((OPTIND-1))case $# in&nbsp; &nbsp; 0 )&nbsp; &nbsp; &nbsp; &nbsp; if [ -n "$abort" ]; then&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanup_autorebase&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rebase_all_intelligent&nbsp; &nbsp; &nbsp; &nbsp; fi&nbsp; &nbsp; &nbsp; &nbsp; ;;&nbsp; &nbsp; * )&nbsp; &nbsp; &nbsp; &nbsp; print_help&nbsp; &nbsp; &nbsp; &nbsp; exit 1&nbsp; &nbsp; &nbsp; &nbsp; ;;esac自从我最初解决这个问题以来,我发现的一件事是有时答案是您实际上根本不想变基!首先要在正确的共同祖先启动主题分支,然后再尝试不推动它们前进,这是有话可说的。但这是在您和您的工作流程之间。

莫回无

如果需要更新提交者日期,GIT_COMMITTER_DATE则可以使用环境变量(手动)。也可以使用--formatoption获得分支名称,而无需其他格式。export GIT_COMMITTER_DATE=$( date -Iseconds )git branch --format='%(refname)' --contains C | xargs -n 1 | git rebase -p --onto master C^unset GIT_COMMITTER_DATE# don't forget to unset this variable to avoid effect for the further work注意:需要为--committer-date-is-author-date或设置GIT_COMMITTER_DATE相同的校验和C',或保证相同的校验Ca'和并Cb'提交(分别在重定基础功能,功能 -a 和功能-b上)。
打开App,查看更多内容
随时随地看视频慕课网APP