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.
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
-
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 -ti --rm -v $(pwd):/git --entrypoint /bin/sh alpine/git
-
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.
- Add assertion shells scripts for all use cases to validate the solution
- Add git snensitive shell PS1 for the docker image
- Add collapsible hints and explanations for each case
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
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"
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"
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"
I did a wrong checkout And now my HEAD is in "detached" state
Run: detached_head.sh
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"
Attention trap ahead !
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"
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"
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"
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"
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"
I squashed some commits But have not yet pushed to origin I want to revert my squash
Run: "revert_squash.sh"
I squashed some commits Then I pushed with --force I want to revert my squash
Run: "revert_squash_pushed.sh"
I worked on a feature and I wanted to rebase upon main But instead I did a merge
Run: "accidental_merge.sh"
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
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
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
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 /.git-repos/multiple_remotes_get_main-upstream.git
Run: multiple_remotes_update_main.sh
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
I have some files in my stash I want to see the state of "file1.txt" in my stash
Run: stash_fun.sh
I want to transfer current branch to new GIT repository as a new project
I want to ignore the dist directory
Run: ignore_dist.sh
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
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
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