git-training-usecases
git-training-usecases copied to clipboard
Git Training Use Cases
This repository is a list of git usecases that are commonly encountered during devleopment. Its primary goal is to show you how you can get into a delicate situation and train you how to solve it.
Usage
Each test case is associated with a POSIX shell script that prepares a local repository located in the workspace directory.
Normally you will do the following for most use-cases:
- Run the associate .sh script
- cd workspace/<use_case_name>
- Solve the problem using git commands
Technical Notes
-
Each script will clean the workspace and you will get a fresh start
-
A remote repository is configured in the .git-repos directory by using the file:// protocol. This means that "git remote -v" will output something like /home/alexander/git-training-usecases/.git-repos/
. -
If you don't have global username and email configured default values will be put for you in the workspace repos.
-
Git "lg" and "s" aliases are configured to use a pretty print git history and for status. Usage: "git lg" and "git s"
-
As a best practice and for security reasons you can run the exercises in a docker image:
docker run --rm --name git-exercises -v $(pwd):/git -it sashokbg/git-exercises /bin/zsh -
Note that after running with docker you may need to manually clean the workspace and .git-repos directories with "sudo".
-
Some test cases run interactive rebases and generate a "fake_editor.sh" script that simulates the user input. This works using the GIT_EDITOR and GIT_SEQUENCE_EDITOR env variables.
TODO
- [ ] Add assertion shells scripts for all use cases to validate the solution
- [x] Add git snensitive shell PS1 for the docker image
- [ ] Add collapsible hints and explanations for each case
Use Cases
Use Case: Abort a merge
I accidentally typed the git merge feat command and now I am prompted a message for the merge.
I want to abort this merge.
Traps:
- If you close the file or save and close the merge will happenRun:
./abort_a_merge.sh
cd workspace/abort_a_merge
Use Case: Merge a feat into main with no merge commit
I finished working on my feature And I want to merge my code to main But I do not want to generate a merge commit In order to keep history clean and linear
Run:
./no_merge_to_main.sh
cd workspace/no_merge_to_main
Use Case: Get Most Recent Code from Main
I work on a "feature" branch And a colleague of mine did a fix that is on "main" branch I want to "get" my colleague's code on my branch.
Run:
./get_most_recent_code_from_main.sh
cd workspace/get_most_recent_code_from_main
Use Case: Undoing a bad commit that is pushed
I did a bad commit introducing a bug that got into production and is on "main" I want to quickly revert so that we can redeploy last version
Run:
./undo_pushed_commit.sh
cd workspace/undo_pushed_commit
Use Case: Undoing a range of pushed bad commit
I did a 3 bad commits introducing a bug that got into production and is on "main" I want to quickly revert them.
Run:
./undo_pushed_range_commits.sh
cd workspace/undo_pushed_range_commit
Use Case: Detached Head
I did a wrong checkout And now my HEAD is in "detached" state
Run:
./detached_head.sh
cd workspace/detached_head
Use Case: Redo last commit
I did a commit but I want to add some files to it. I want to push my code to the remote
Run:
./redo_last_commit.sh
cd workspace/redo_last_commit
Attention trap ahead !
Use Case: Clean a WIP commit
I worked on a feature And I had to quickly change a branch so I performed a "WIP" commit at one point. I want to clean this WIP commit before opening my merge request.
Solve for:
- I want to rename the wip commit
- I want to drop the wip commit
- I want to rename the wip AND the last commit to have (first, second, third, fourth)
- I want to fuse the wip commit with the previous commit
- I want to fuse the wip commit with the next commit
Run:
./clean_wip_commit.sh
cd workspace/clean_wip_commit
Use Case: Too many commits
I worked on a feature and did too many commits I wish to fuse them together before opening a merge request.
Run:
./too_many_commits.sh
cd workspace/too_many_commits
Use Case: Edit a previous commit (not last)
I did two commits: one for backend and then one for frontend But I forgot to add one file in the backend commit
Run:
./edit_second_to_last_commit.sh
cd workspace/edit_second_to_last_commit
Use Case: Quickly change branch
I am working on a feature and have not yet commited But I need to quickly change branch to main to fix an urgent issue.
Run:
./quickly_change_branch.sh
cd workspace/quickly_change_branch
Use Case: A non-tracked file is changed on another branch
I have a non-tracked file called file2.txt This file exists in the "main" branch When I try to checkout "main" I encountered the following error
error: The following untracked working tree files would be overwritten by checkout:
file.txt
Please move or remove them before you switch branches.
Aborting
Run:
./non_tracked_file_checkout.sh
cd workspace/non_tracked_file_checkout
Use Case: Revert a Rebase
I squashed some commits But have not yet pushed to origin I want to revert my squash
Run:
./revert_squash.sh
cd workspace/revert_squash
Use Case: Revert a Rebase That was Pushed
I squashed some commits Then I pushed with --force I want to revert my squash
Run:
./revert_squash_pushed.sh
cd workspace/revert_squash_pushed
Use Case: Accidental merge from main
I worked on a feature and I wanted to rebase upon main But instead I did a merge
Run:
./accidental_merge.sh
cd workspace/accidental_merge
Use Case: Rebase Conflict Resolution
I edited the text1.txt file I want to rebase my feat branch onto main But another user edited the same file on main
Run:
./rebase_conflict.sh
cd workspace/rebase_conflict
Use Case: Split a commit
I did one big commit that has too many changes I want to split it into three commits "split: 1", "split: 2" and "split: 3"
Run:
./split_commit.sh
cd workspace/split_commit
Use Case: Branch merged upon itself
Me and a colleague worked on the same branch They commited a change on file1.txt I do a pull of the branch But and it generates a merge
Run:
./pull_generates_merge.sh
cd workspace/pull_generates_merge
Use Case: Multiple Origins - Get Second Remote Main
I forked a repository from a remote Someone has pushed some new code to the original remote in branch main I want to get the latest changes from the original remote (The second remote is found at .git-repos/
Hint: Use the file:// protocol for the second remote and point at
Run:
./multiple_remotes_update_main.sh
cd workspace/multiple_remotes_update_main
Use Case: Take File Version from Another Branch
I am working on a branch feat And I want to get the version of file "file1.txt" from the "feat/other" branch
Run:
./take_file_another_branch.sh
cd workspace/take_file_another_branch
Use Case: Preview my stash
I have some files in my stash I want to see the state of "file1.txt" in my stash
Run:
./stash_fun.sh
cd workspace/stash_fun
Use Case: I want new GIT repo from current branch
I want to transfer current branch to new GIT repository as a new project
Use Case: I want to ignore a directory but something is off
I want to ignore the dist directory
Run:
./ignore_dist.sh
cd workspace/ignore_dist
Use Case: I want to send a piece of code to another repo
I work on a repository that uses the same code as another repo I want to send my last commit to a colleague that is working on the other repo
Run:
./send_code_from_here.sh
cd workspace/send_code_from_here
Use Case: Create a branch results in "refs/heads/..." exists
I try to create a branch called "feat/my_feat" But it results in an error "refs/heads/my_feat" exists. Cannot create ...
Run:
./checkout_error_ref_exists.sh
cd workspace/checkout_error_ref_exists
Use Case: I see the commits of my colleague in my PR
I did some wrong operation And now I see the commits of my colleague as part of my PR
Run:
./foreign_commits_on_my_branch.sh
cd workspace/foreign_commits_on_my_branch
Use Case: Pulling from another repository fails
A colleague works on another repository that is not related to mine and have pushed a commit called "other commit". I want to get the content of their commit on my repo.
I added the second repository as a remote and pulled
And I receive the following error when trying merge
fatal: refusing to merge unrelated histories
Run:
./cannot_merge_unreleated_history.sh
cd workspace/cannot_merge_unreleated_history.sh