添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft Edge More info about Internet Explorer and Microsoft Edge

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019 | TFS 2018

Visual Studio 2019 | Visual Studio 2022

Git automatically maintains a history of development on a branch by linking each new commit to its predecessor. When you merge one branch into another, the history can become less straightforward. For example, a no-fast-forward merge combines divergent lines of development by creating a merge commit with multiple predecessors. Conversely, a Git rebase combines divergent lines of development without creating a merge commit, which results in a simpler commit history but loses information about the merge. Your choice of merge type is likely influenced by whether you want to preserve a record of the merge or simplify the commit history.

This article discusses when to use a rebase instead of a no-fast-forward merge, and provides procedures for the following tasks:

  • Rebase your local branch
  • Force push your local branch after a rebase
  • Interactive rebase to squash local commits
  • For an overview of the Git workflow, see Azure Repos Git tutorial .

    Rebase your local branch

    Git rebase integrates commits from a source branch into your current local branch (target branch). The source branch remains unchanged. For comparison, Git rebase and other merge types are shown in the following diagram.

    Git rebase resequences the commit history of the target branch so that it contains all source branch commits, followed by all target branch commits since the last common commit. Another way to view it is that a rebase replays the changes in your target branch on top of the source branch history. Notably, Git rebase changes the sequence of the existing target branch commits, which isn't the case for the other merge strategies. In the preceding diagram, commit K' contains the same changes as K, but has a new commit ID because it links back to commit E instead of C.

    During a rebase, if a source branch change conflicts with a target branch change, Git will prompt you to resolve the merge conflict . You can resolve merge conflicts during a rebase in the same way that you resolve merge conflicts during a merge.

    Rebase vs. no-fast-forward merge

    Git rebasing results in a simpler but less exact commit history than a no-fast-forward merge, otherwise known as a three-way or true merge. When you want a record of a merge in the commit history, use a no-fast-forward merge.

    If you're the only person working on a feature or bugfix branch, consider using a rebase to periodically integrate recent main branch work into it. That strategy helps ensure that you stay aware of recent work by others and promptly resolve any merge conflicts that arise. By rebasing, you implement your new feature on top of the most recent main branch work, which helps maintain a linear commit history.

    For more information on Git rebase and when to use it, see Rebase vs merge .

    Rebase and force-push guidelines

    If you rebase a local branch that you've previously pushed , and then run the default Git push command again, the push will fail. The default Git push command applies a fast-forward merge to integrate your local branch into the remote branch. That command will fail after a rebase because the rebase alters the sequence of existing commits in your local target branch, so it no longer matches the history of its remote counterpart. In this scenario, a force push will succeed—by overwriting the remote branch.

    Git rebase and force push are powerful tools, but keep these guidelines in mind when deciding whether to use them:

  • Don't rebase a local branch that's been pushed and shared with others, unless you're certain no one is using the shared branch. After a rebase, your local branch will no longer match the history of its remote counterpart.
  • Don't force push to a remote branch that's in use by others, since their local version of the remote branch will no longer match the updated remote branch history.
  • Your team should agree on the usage scenarios for rebase and force push.
  • For a collaborative review process, use a pull request to merge new work into the default branch of a remote repo.

    How to rebase

    Visual Studio 2022 Visual Studio 2019 - Git menu Visual Studio 2019 - Team Explorer Git Command Line

    Visual Studio 2022 provides a Git version control experience by using the Git menu, Git Changes , and through context menus in Solution Explorer . Visual Studio 2019 version 16.8 also offers the Team Explorer Git user interface. For more information, see the Visual Studio 2019 - Team Explorer tab.

  • Choose Git > Manage Branches to open the Git Repository window.

    Visual Studio 2019 provides a Git version control experience by using the Git menu, Git Changes , and through context menus in Solution Explorer .

  • Choose Git > Manage Branches to open the Git Repository window.

    Visual Studio 2019 version 16.8 and later versions provides a Git version control experience while maintaining the Team Explorer Git user interface. To use Team Explorer , uncheck Tools > Options > Preview Features > New Git user experience from the menu bar. You can use Git features from either interface interchangeably.

  • In Team Explorer , select Home and choose Branches .

    To integrate source branch commits into a target branch, run the git rebase command:

    git rebase <source branch name> <target branch name>
    

    If your current local branch is the target branch, you can simplify the rebase command to:

    git rebase <source branch name>
    

    Git will notify you if there are conflicts during the rebase. You can either resolve the conflicts and then run git rebase --continue, or run git rebase --abort to undo the rebase and return to the pre-rebase state.

    Force push your local branch after a rebase

    If you rebase a local branch that you've previously pushed, a subsequent default Git push will fail. Instead, you can force push your local branch to overwrite its remote counterpart so that their commit histories match.

    Warning

    Never force push a branch that others are working on. For more information, see Rebase and force push guidelines.

    To force push in Visual Studio, you must first enable the force push option:

  • Go to Tools > Options > Source Control > Git Global Settings.

  • Select the Enable push --force-with-lease option.

    The Git push --force-with-lease flag is safer than the --force flag because it won't overwrite a remote branch that has commits that aren't integrated within the local branch you're force pushing.

    Visual Studio 2022 Visual Studio 2019 - Git menu Visual Studio 2019 - Team Explorer Git Command Line

    Visual Studio 2019 version 16.8 and later versions provides a Git version control experience while maintaining the Team Explorer Git user interface. To use Team Explorer, uncheck Tools > Options > Preview Features > New Git user experience from the menu bar. You can use Git features from either interface interchangeably.

  • In Team Explorer, select Home and then choose Sync to open the Synchronization view.

    The Git push --force-with-lease flag is safer than the --force flag because it won't overwrite a remote branch that has commits that aren't integrated within the local branch you're force pushing.

    To force push new commits from your local branch to a same-named remote branch:

    git push --force-with-lease <remote> <local branch name>
    

    If the branch you want to push is your checked out branch, you can simplify the force push command to:

    git push --force-with-lease <remote>
    

    When you clone a remote repo, Git assigns the alias origin as shorthand for the URL of the remote repo that you cloned. Run git remote -v to check the origin alias value. To add the origin alias manually, run git remote add origin <remote repo url>. With the origin alias, you can further simplify the force push command:

    git push --force-with-lease origin
    

    If your current local branch tracks a remote branch on origin, you can fully abbreviate the force push command:

    git push --force-with-lease
    

    However, the fully abbreviated push command will fail if your local branch doesn't track a remote branch. Run git remote show origin to check the tracked status of your branches.

    Interactive rebase to squash local commits

    Typically, as you work on a new feature in your local feature branch, you'll create multiple commits. When you're ready to publish the new feature, you might want to consolidate those commits into a single commit to simplify the commit history. You can use an interactive rebase to squash multiple commits into a single commit.

    Visual Studio 2022 Visual Studio 2019 - Git menu Visual Studio 2019 - Team Explorer Git Command Line
  • Check out the local branch that you want to perform an interactive rebase on.

  • Commit, stash, or discard any uncommitted changes.

  • Estimate how far back in the commit history you want to go. You don't have to be exact as you'll get to pick out specific commits to squash when you run the interactive rebase command. For example, if you want to squash commits within the last five commits, run:

    git rebase -i HEAD~5
    

    Git will open an editor that lists the last five commits, starting with the most recent. For example:

    pick 7068b09 Update README network switch section
    pick 9d247f7 Update README network controller section
    pick 5d7ab9f Fix fiber optic transmitter test
    pick 7b43f3f Add network switch test
    pick 00859d9 Add network controller test
    
  • Leave the first line as is. On subsequent lines, to merge a commit with the one above it, change pick to squash. For example, to combine the top two commits and also the bottom two commits, modify the commit list to:

    pick 7068b09 Update README network switch section
    squash 9d247f7 Update README network controller section
    pick 5d7ab9f Fix fiber optic transmitter test
    pick 7b43f3f Add network switch test
    squash 00859d9 Add network controller test
    
  • Save and close the editor. Git will then open a new editor for each set of merged commits, prompting you to enter a commit message. For each commit set, condense the commit messages down to one message, then save and close the editor. In the preceding example, the squashed commits are condensed with new commit messages:

    8fcb88f Update README network sections
    ac6d3c0 Fix fiber optic transmitter test
    f0aadc3 Add two network tests
    

    Even though the commit Fix fiber optic transmitter test wasn't squashed, it has a new commit ID because it now links to a different predecessor commit.

    For more information about interactive rebasing, see Git rebase interactive mode.

    Azure DevOps users can squash merge to condense the commit history of a topic branch during a pull request.

    Next steps

    Copy changes with cherry-pick

  • New to Git repos? Learn more
  • Share code with push
  • Update code with fetch, merge, and pull
  •