8000 GitHub - LensArt/rebase-training: Repo for training Git rebasing
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

LensArt/rebase-training

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rebase Training Repo

This Git repository gives you examples on how you can train/experiment with Git's rebasing feature. The CLI part shows some additional options besides rebasing to train/experiment with keeping your git history clean.

You can train following things here:

Sourcetree:

  1. Rebase
  2. Interactive rebase (squashing and other options)
  3. Commit amend
  4. Pushing rebased changes

CLI:

  1. Rebase
  2. Interactive rebase (squashing and other options)
  3. Rebase options like continue, skip and abort.
  4. Git reset
  5. Commit amend
  6. Pushing and pulling rebased changes

Getting Started

Follow these instructions to clone the repository into a clean state where you can train:

$ cd <an-empty-dir>
$ git clone -b rebase/master https://github.com/LensArt/rebase-training.git .
$ git checkout --track origin/rebase/feature/multiply

Note: If something went wrong, you can delete the impacted branch and download it again from the remote or you can delete the whole directory and re-clone the repository to try again.

Sourcetree

Rebase (without Squash)

Rebasing allows you to 'rebase' your changes on top of another branch or on top of new changes pushed to the branch you branched off.

  1. Open the "Log / History" tab
  2. Checkout source branch (rebase/feature/multiply)
  3. Right-click head of target branch (rebase/master) and select "Rebase..."
  4. Resolve conflict via the "File Status" tab (Right-click on Program.cs and chose "Resolve Conflict")
  5. In the menu choose "Action" -> "Continue Rebase"

Rebase Interactively (with Squash)

Interactive rebasing allows you to squash, delete and reorder commits before rebasing them onto a different branch.

Unfortunately, Sourcetree contains an ancient bug; so this feature doesn't fully work.

My current workaround: First do a regular rebase, then do the interactive rebase.

  1. Rebase source branch (rebase/feature/multiply) on target branch (rebase/master)
  2. Open the "Log / History" tab
  3. Right-click the parent of oldest commit you want to rebase interactively (here 5c3d0ea) and select "Rebase children of xxx interactively..."
  4. Modify the commits as desired (check out this video for all the options)

Amend changes

Sometimes you want to add a fix to your last commit, in this case you can amend the changes to your commit.

  1. Stage your changes in sourcetree
  2. Select in the commit options dropdown (right upper corner above the commit message entry) Amend latest commit.
  3. It will show you a popup if you want to replace you commit message, if you select Yes it will copy the commit message from the last commit in the commit message entry box.
  4. You can edit this message if desired and commit your changes.

To push your changes see below how to force push

Pushing Changes

Once you're done you (probably) need to push your changes back to origin. Normally Git doesn't allow you to push these kinds of changes.

Instead you need to "force push" them; ideally by using --force-with-lease instead of --force. You can read about the differences between those two in this article.

To be able to do a "force push" with Sourcetree, this needs to be enabled in the options.

In the menu, go to "Tools" -> "Options" -> "Git" and check "Enable Force Push". Make sure to also check "Use Safe Force Push".

Then you can select "Force Push" in "Push" dialog. (No matter the name, this will automatically use --force-with-lease instead of --force when "Use Safe Force Push" is enabled in the options.)

CLI

Rebase (without Squash)

Rebasing allows you to 'rebase' your changes on top of another branch or on top of new changes pushed to the branch you branched off.

  1. Checkout source branch (git checkout rebase/feature/multiply)
  2. Rebase head of target branch (git rebase rebase/master)
  3. You can optionally show the conflict in cli (git diff) enter q to exit
  4. Resolve conflict in your favorite text editor
    • To see the beginning of the merge conflict in your file, search the file for the conflict marker <<<<<<<. When you open the file in your text editor, you'll see the changes from the HEAD or base branch after the line <<<<<<< HEAD. Next, you'll see =======, which divides your changes from the changes in the other branch, followed by >>>>>>> BRANCH-NAME. In this tutorial, one person wrote "case Operator.Subtract:..." in the base or HEAD branch and another person wrote "case Operator.Multiply:..." in the compare branch or rebase/feature/multiply. In some cases you want to keep both changes, in other cases you want to replace one of the 2 changes. If you want to keep both changes, keep an eye on the line before and after the conflict to see if you need to copy those to complete the conflict fix.
        ++<<<<<<< HEAD
        +                 case Operator.Subtract:
        +                     result = RunSubtract(operand1, operand2);
        ++=======
        +                 case Operator.Multiply:
        +                     result = RunMultiply(operand1, operand2);
        ++>>>>>>> 5062359 (Feature: Implemented multiply operation)
    
  5. Add the fixed file (git add .)
  6. Continue the rebase (git rebase --continue)
    • This will show a vim screen with the commit message, you can change the message if needed. You can quit and continue with :q. Look for basic vim explanation here.

Rebase Interactively (with Squash)

Interactive rebasing allows you to squash, delete and reorder commits before rebasing them onto a different branch.

  1. Checkout source branch (git checkout rebase/feature/multiply)
  2. Rebase interactively head of target branch (git rebase rebase/master -i)
    • This will show a vim screen with the options and commit messages
    • You can change the action if needed in front of the commit.
      • For instance you can change an action default pick to f: start edit mode in vim by pressing i remove pick from the line and enter f, next press escape to stop the edit mode in vim.
    • You can quit and write to continue with :wq.
    • Look for basic vim explanation here.

Rebase skip

Sometimes you have branched off a branch which has new or amended changes to commits which you also have in your branch. If you rebase on the new changes of this branch you will see these new or amended as conflicts in the rebasing process. In that case you can skip the current commit to continue the rebase.

  1. Checkout source branch (git checkout rebase/feature/refactor)
  2. Rebase head of target branch (git rebase rebase/feature/multiply)
  3. You will see a merge conflict on a commit which has been fixed in the rebase/feature/multiply branch, if you would fix the merge conflict you would end up with an empty diff. This is where git rebase --skip comes into play. With the skip command you will skip (basically drop) this commit from the branch you are rebasing and continue with the next commits on your branch. Since the commit is already part of the branch rebase/feature/multiply you don't need it anymore in your branch (rebase/feature/refactor).

Rebase abort

In order to stop an ongoing rebase process you can use git rebase --abort to go back to the original state.

Git reset

Sometimes it can be interesting to use git reset .. this undoes changes. It will remove the commits from history (or better stated point the HEAD and branch ref to a specified commit) and restore all changes to your local system showing them in your diff.

  1. Checkout source branch (git checkout rebase/feature/multiply)
  2. Undo last commit by using git reset d0b2d6f this will show the last committed files in the diff as unstaged changes. You can do some changes to the unstaged files, stage them and commit. But for now we won't.
  3. Undo 2nd last commit by using git reset 20294f3. As in our case the first commit undoes the 2nd, it will leave the diff empty and show you can pull 2 commits from the remote. You could force push to remove both commits from the history.

In real world scenarios most likely you wouldn't end up with an empty diff, but this git reset .. option gives you the ability to change your commits or revert or edit some committed changes.

Optionally you can add the --hard option to also remove the staged changes from the undone commits.

Git reset specific file

You can also reset a single or multiple file(s) (space separated) in a commit, doing this will leave the rest of the commit intact, and just reset the specified file(s). You can then revert the changes to this file or change the file and amend to the existing commit.

  1. Checkout source branch (git checkout rebase/feature/refactor)
  2. Reset Program.cs git reset 20294f3 Calculator\Calculator\Program.cs
  3. You will see Program.cs both as staged and unstaged file. The staged part reflects the reverted changes compared to what is in the commit and the unstaged part reflects the changes which were committed. If you would stage the unstaged changes unedited you will end up with an empty diff. If you would edit the file you would see those changes as diff if you stage them.

Amend changes

Sometimes you want to add a fix to your last commit, in this case you can amend the changes to your commit.

  1. Use git commit -a --amend to stage and amend all your changes to your last commit.
  2. This will show a vim screen with the option to change the commit message.

To push your changes see below how to force push

Pushing Changes

Once you're done you (probably) need to push your changes back to origin. Normally Git doesn't allow you to push these kinds of changes.

Instead you need to "force push" them; ideally by using --force-with-lease instead of --force. You can read about the differences between those two in this article.

So to push the changes to origin you can either use git push -f to force push or better git push --force-with-lease to force push with lease.

Pulling Changes

To pull changes which were force pushed by someone else you can use git pull --rebase.

Summary

A quick summary of the git commands and what they do:

Git rebase

  • git rebase [branch_or_commit] rebase the current branch on the branch in the command.
  • git rebase [branch_or_commit] -i interactively rebase the current branch on the branch in the command.
  • git rebase --continue commit fixes on current commit and continue to the next commit on the branch which is being rebased.
  • git rebase --skip drops the commit from the branch which is being rebased.
  • git rebase --abort stop an ongoing rebase.

Git reset

  • git reset [branch_or_commit] undo commits and point the HEAD and branch ref to the specified branch/commit.
  • git reset [branch_or_commit] --hard undo commits and point the HEAD and branch ref to the specified branch/commit and clear all staged changes.
  • git reset [branch_or_commit] [file_path(s)] undo changes to a specific file and leave the rest of the commit intact.

Commit amend

  • git commit -a --amend stage and amend (add) all files to the previous commit.

Pushing and pulling changes

  • git push --force-with-lease force push with lease (check if remote has no new changes)
  • git push -f force push
  • git pull --rebase pull rebased changes from remote

possible other helpful commands

  • git log view commit history of the current branch.
  • git status check local repo status and show modified files.
  • git diff shows diff of what is changed but not staged.
  • git commit -am "" stage and commit all files with specified commit message.

Additional resources

About

Repo for training Git rebasing

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 100.0%
0