Skip to content

Commit

Permalink
update force-pull activity
Browse files Browse the repository at this point in the history
  • Loading branch information
brianamarie committed Jan 16, 2019
1 parent aec5579 commit cf2cf33
Show file tree
Hide file tree
Showing 20 changed files with 268 additions and 190 deletions.
12 changes: 12 additions & 0 deletions 00-assumptions.md/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### Assumptions
- Basic Git knowledge
- enough to be dangerous

### Things to know

1. This will use `git reset`, so you should first check that:
- The commits in question are _only local_.
- There are no unintended files in your working or staging directory.

2. git lol is set for every exercise
2. most activities start by CD'ing into the directory
19 changes: 8 additions & 11 deletions 01-committed-too-big/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
### Commit is too big

How can I commit only part of a file in Git? (Or, revise commits where I committed too much?)

1. Run `. setup.sh`

Look at the files and history that's been created. You'll see that several files and a history have been created. We want to change the history so the commits are more logical.

First, we need to move those changes back into the working directory so we can re-stage and re-commit.

2. `git reset reset-here` to a certain commit, bringing the changes that should be broken up into the working directory.
3. Use `git add -p` to be specific about how commits are formed. You can use `s` to split even further.
4. When you're done with the activity, run `. reset.sh`.
> That commit is too big. It should have been broken up into several commits.
1. Change directories into the activity file: `cd 01-committed-too-big`
2. Run `. setup.sh`
3. Look at the files and the history: `ls` and `git lol`
3. `git reset reset-here` to a certain commit, bringing the changes that should be broken up into the working directory
4. Use `git add -p` to be specific about how commits are formed. You can use `s` to split even further.
5. When you're done with the activity, run `. reset.sh` and `cd ..`
26 changes: 11 additions & 15 deletions 02-accidental-commit-to-master/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
### Accidental Commit

I committed to master instead of a branch!
> I committed to master instead of a branch!
This will use `git reset`, so you should first check that:
- The commits in question are _only local_.
- There are no unintended files in your working or staging directory.

#### Getting started
1. Run `. setup.sh`.
- This sets a local alias, `git lol`. Use `git lol` and `git status` to see the current state of your repository.
2. Use `git reset` back to the last commit that was meant to be on master.
- Normally, you could use `git reset origin/master`. For today, use the `reset-here` tag: `git reset reset-here`.
- Use `git lol` and `git status` again.
3. Create a new branch and checkout to it with `git checkout -b experiment`. (Your working and staging area will come with you!)
4. Stage your changes, and make a commit.
- :tada: Yay, the commit is now where it should be!
5. Once you're finished, run `. reset.sh`.
1. Change directories into the activity file: `cd 02-accidental-commit-to-master`
2. Run `. setup.sh`
3. Use `git lol` and `git status` to see the current state of your repository
4. Reset back to the last commit that was meant to be on master: `git reset reset-here`
- Alternatively, you could reset to `origin/master` also
5. Use `git lol` and `git status` again
6. Create a new branch and checkout to it with `git checkout -b experiment`
- Notice your working and staging area will come with `HEAD`
7. Stage your changes, and make a commit
8. Once you're finished, run `. reset.sh` and `cd ..`
Empty file.
15 changes: 7 additions & 8 deletions 03-detached-head/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
### I'm in a detached head state

1. Run `. setup.sh`
> Git says I'm in a "detached head state" and I don't know what to do.
A detached head state only means that your `HEAD` pointer is currently pointed _not_ to a branch.

2. You can see this by typing `git lol` (an alias was set in the setup script)

To fix this, to get your `HEAD` attached, you need to point to a branch. You can do this by checking out to an existing branch, or creating a new branch where you are.

3. Let's create a new branch where we are with `git checkout -b more-work`

Now, you're no longer in a detached head state. You can continue working normally on your new branch.

4. Reset the activity with `. reset.sh`
1. Change directories into the activity file: `cd 03-detached-head`
2. Run `. setup.sh`
3. See where your `HEAD` is pointing with `git lol`
4. Let's create a new branch where we are with `git checkout -b more-work`
- Now, you're no longer in a detached head state, and can continue working normally on your new branch
5. Reset the activity with `. reset.sh` and `cd ..`
38 changes: 16 additions & 22 deletions 04-what-broke-this/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
### What broke my code?

Something's been broken, but I don't know what commit broke it.
> Something's been broken, but I don't know what commit broke it.
There's a test in this directory, checking if any file is empty or not.
There's a test in this directory, checking if any file is empty or not. This only _finds_ the commit introducing the break, it doesn't fix it at all.

1. `ls`
1. `. test.sh`

To get set up, run the scripts:

2. `. setup.sh`
3. `. test.sh` to find something's broken

Before you can use bisect, you need to be in the root directory of the repository.

1. `cd ..`
1. `. 04-what-broke-this/test.sh`
1. `git bisect start`
1. `git bisect bad HEAD`
1. `git bisect good before-activity4`
1. `. 04-what-broke-this/test.sh`
1. `git bisect good` or `git bisect good`, depending on the results of the test
1. Continue until it finds the commit
1. `git bisect reset`
1. `. 04-what-broke-this/reset.sh`
1. Change directories into the activity file: `cd 04-what-broke-this`
2. See the test with `ls`, and try it with `. test.sh`
3. To get set up, run the scripts `. setup.sh`
4. Use the test `. test.sh` to find if something's broken
5. Before you can use bisect, you need to be in the root directory of the repository: `cd ..`
6. Try the test again: `. 04-what-broke-this/test.sh`
7. Begin the bisect: `git bisect start`
8. Tell Git where the "broken" commit is: `git bisect bad HEAD`
9. Tell Git where the last known "good" commit was: `git bisect good before-activity4`
10. After Git moves your `HEAD` pointer to a different commit, try your test again: `04-what-broke-this/test.sh`
11. Depending on the results of the test, type `git bisect good` or `git bisect good`
12. Continue until Git finds the commit
13. Exit the bisect: `git bisect reset`
14. Reset the files: `. 04-what-broke-this/reset.sh`
20 changes: 9 additions & 11 deletions 05-merge-two-repos/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
### I want to merge two repositories

1. Run the setup script: `. setup.sh`
1. Add the other repository as a second remote: `git remote add other-repo https://github.com/brianamarie/another-repository.git`
1. Before you try to merge, make sure you have all of the remote tracking branches for all remotes: `git fetch --all`
1. Try to merge the two repositories: `git merge other-repo/master` and notice the error message.
1. Since these two repositories have unrelated histories, we need to specify a particular type of merge: `git merge other-repo/master --allow-unrelated-histories`.

In practice, we would probably want to create a new repository to have the combined histories of both of the other repositories. Then, it would be best to archive the singular repositories.
> There are two separate project repositories that should be in one repository, but they have unrelated histories.
1. You can see the combined history with the alias `git lol`
In practice, you might want to create a new repository to have the combined histories of both of the other repositories. Then, it would be best to archive the singular repositories.

Reset the exercise.

1. `. reset.sh`
1. Run the setup script: `. setup.sh`
2. Add the other repository as a second remote: `git remote add other-repo https://github.com/brianamarie/another-repository.git` OR `. add-remote.sh`
3. Before you try to merge, make sure you have all of the remote tracking branches for all remotes: `git fetch --all`
4. Try to merge the two repositories: `git merge other-repo/master` and notice the error message.
5. Since these two repositories have unrelated histories, we need to specify a particular type of merge: `git merge other-repo/master --allow-unrelated-histories`
6. You can see the combined history with the alias `git lol`
7. Reset the exercise: `. reset.sh` and `cd ..`
3 changes: 3 additions & 0 deletions 05-merge-two-repos/add-remote.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

git remote add other-repo https://github.com/brianamarie/another-repository.git
16 changes: 9 additions & 7 deletions 06-revert-merge/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
### I want to undo a recursive merge (without GitHub)

1. Run `. setup.sh`
2. Look at the log, and take lineage of commits' parents into account: `git lol` (alias set during script)
3. Identify which branch is the "parent" branch of the merge. (The branch you were on when you merged is the parent, so we will refer to it as "1".) The parent in this case is `md-files`. We want to revert the merge, and _keep_ the files that were originally on this branch, the markdown files.
4. Identify the merge commit.
5. Revert the merge commit: `git revert -m <parent> <commit>`.
> A merge happened locally, and then I pushed. I'd like to revert the merge and maintain all of committed history.
- ex: `git revert -m 1 cd4370f`
When reverting a merge, Git wants to know about the "parent" commits. The branch you were on when you merged is the parent, so we will refer to it as "1".

1. Run `. setup.sh`
2. Look at the log, and take lineage of commits' parents into account: `git lol`
3. Identify which branch is the "parent" branch of the merge, `md-files` in our case
4. Identify the merge commit
5. Revert the merge commit: `git revert -m <parent> <commit>`
- ex: `git revert -m 1 cd4370f`
6. Look at the files and the log: `git lol`, and `ls`
7. Reset the activity: `. reset.sh`
7. Reset the activity: `. reset.sh` and `cd ..`
17 changes: 12 additions & 5 deletions 07-forget-binary/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
I committed a binary file a long time ago, how to make git forget about a file that was tracked but is now in .gitignore?
### I need Git to ignore a binary file

> I committed a binary file a long time ago, how to make git forget about a file that was tracked but is now in .gitignore?
When files are defined in the `.gitignore` from the start, Git will always ignore them. But, if a file is already tracked by Git, adding the name to the `.gitignore` doesn't do any good.

1. Run `. setup.sh`, then notice your history and working directory
2. Create a `.gitignore` file in the _root directory_ of this repository
3. Add `test.img` to the `.gitignore` file
4. Add and commit the `.gitignore` file
4. Change directories back into this activity: `cd 07-forget-binary`
4. Change the big binary file `. change-binary.sh`
5. Add and commit the large binary file.
- What did you expect to happen? Git knows the file based on its similarity index, not by the name, so it's not untracking it at all.
6. For Git to ignore a file that is already being tracked, you need to run: `git rm --cached <file>`.
- It should be noted that in general you also will want to get rid of these files! Tune in to Lars' session later. :wink:
5. Add and commit the binary file.
- What did you expect to happen? Git knows the file based on its similarity index, not by the name, so it's still tracked.
6. For Git to ignore a file that is already being tracked, you need to remove the cache: `git rm --cached test.img`

> Note: this does not remove the file from history, only from tracking and any _new_ commits.
1 change: 1 addition & 0 deletions 07-forget-binary/reset.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash

git checkout master
rm -rf test.img
git reset --hard before-activity7
git tag -d before-activity7
24 changes: 13 additions & 11 deletions 08-remove-submodule/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
### How do I remove a submodule?

1. Add a submodule with the script: `. setup.sh`
2. Notice there is a submodule with: `cat .gitmodules`
3. "deinit" the submodule: `git submodule deinit example-submodule`
4. `git rm <path_to_submodule>`
5. `git commit -m "removed submodule"`
6. `rm -rf .git/modules/<path_to_submoule>`
7. Remove the `.gitmodules` directory from the root directory of the repository:
- `cd ..`
- `rm -rf .gitmodules`
- cd back into the repository: `cd 08-remove-submodule`
8. Reset the repository: `. reset.sh`
> I had needed a submodule in the past, but it's no longer necessary. How do I remove it completely from this repository?
Submodules are sticky business, and if you want out, it takes a few steps.

1. Make sure you're in the root directory of this repository.
2. Add a submodule with the script: `. 08-remove-submodule/setup.sh`
3. Notice there is a submodule with: `cat .gitmodules`
4. Remove the contents of the directory and "de-initialize" the submodule: `git submodule deinit example-submodule`
5. Remove the path that Git uses to keep track of the submodule: `git rm <path_to_submodule>`
6. Commit those changes: `git commit -m "removed submodule"`
6. Remove the reference in the `.git` directory: `rm -rf .git/modules/<path_to_submoule>`
7. Remove the `.gitmodules` directory from the root directory of the repository: `rm -rf .gitmodules`
8. Reset the repository: `. 08-remove-submodule/reset.sh`
17 changes: 12 additions & 5 deletions 09-undo-rebase/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
### I want to undo a rebase

A rebase is done to force a fast-forward merge, and result in a straight line of history.
> I rebased onto the wrong branch!
1. Run `. setup.sh`
2. See the history with `git lol`
3. It's not intuitive or easy to find the correct commit to reset to.
4. Using the `git reflog`, identify the most recent commit by message, and find the last instance of it in the reflog. Use that commit ID for the reset.
A rebase is done to force a fast-forward merge, and result in a straight line of history. To go back, you usually need to use `git reflog`. It's not intuitive or easy to find the correct commit to reset to.

1. Change directories for this activity: `cd 09-undo-rebase`
2. Run `. setup.sh`
- This script creates new commits on master and on the `md-files` branch, then rebases the `md-files` branch onto `master`
3. See the history with `git lol`
- Notice a tag? The script also tagged the commit _before_ the rebase took place.
4. Using the `git reflog`, identify the most recent commit by message, and find the last instance of it in the reflog
5. Use that commit ID or the tag to reset the branch: `git reset --hard before-rebase`
6. See your history, as it was before the reset: `git lol`
7. Reset the activity: `. reset.sh` and `cd ..`
1 change: 1 addition & 0 deletions 09-undo-rebase/reset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
git checkout master
git reset --hard before-activity9
git tag -d before-activity9
git tag -d before-rebase
git branch -D md-files
3 changes: 2 additions & 1 deletion 09-undo-rebase/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ for d in {1..6}; do touch "file${d}.md"; git add "file${d}.md"; git commit -m "a
git checkout master
for d in {1..6}; do touch "file${d}.txt"; git add "file${d}.txt"; git commit -m "adding file ${d} (txt)"; done
git checkout md-files
git rebase master
git tag before-rebase
git rebase master
23 changes: 5 additions & 18 deletions 10-force-pull/conflicts.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
## git-merge - Join two or more development histories together
## `git merge`

### SYNOPSIS
### How is it generally used?
git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
[--[no-]allow-unrelated-histories]
[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>…​]
git merge --abort
git merge --continue

### DESCRIPTION
### What is it?
Incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current branch. This command is used by git pull to incorporate changes from another repository and can be used by hand to merge changes from one branch into another.

Assume the following history exists and the current branch is "master":

A---B---C topic
/
D---E---F---G master
Then "git merge topic" will replay the changes made on the topic branch since it diverged from master (i.e., E) until its current commit (C) on top of master, and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes.

A---B---C topic
/ \
D---E---F---G---H master
The second syntax ("git merge --abort") can only be run after the merge has resulted in conflicts. git merge --abort will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the merge started (and especially if those changes were further modified after the merge was started), git merge --abort will in some cases be unable to reconstruct the original (pre-merge) changes. Therefore:

Warning: Running git merge with non-trivial uncommitted changes is discouraged: while possible, it may leave you in a state that is hard to back out of in the case of a conflict.

The third syntax ("git merge --continue") can only be run after the merge has resulted in conflicts.
### Other meanings
Git Merge is also an event for Git enthusiasts!
1 change: 0 additions & 1 deletion 10-force-pull/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

git config alias.lol "log --oneline --decorate --graph --all"
git tag before-activity10
git checkout conflicting-local-changes
git reset --hard HEAD~1
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Popular shoutouts to:
- Michael Kohn "10 Common Git Problems and How to Fix Them"

### Getting Started
You can view the slides at https://brianamarie.github.io/10-git-problems/#1.
You can view the slides at https://brianamarie.github.io/10-git-problems/#1.

To practice each exercise, `cd` into the corresponding directory. Get started with `. script.sh`, and follow the instructions in the `README.md` of that subdirectory or on the slides.

Expand Down
Loading

0 comments on commit cf2cf33

Please sign in to comment.