training-manual
training-manual copied to clipboard
Add submodule and other advanced information
Does it make sense to put some advanced content outlines in the manual or in this repository?
cc @githubtraining/trainers
- @brianamarie
GitHub for Developers - Day 2 for Advanced Audiences
This outline is a more advanced version of GitHub for Developers day 2 and should only be used if you have finished all of the day 1 material, both merge conflicts in the github-games
activity (including using a second remote to pull in the merge conflict on the second activity), git bisect
and git revert
on the first day of training.
Morning Warm-Up
Step 1
- Find a partner to work with
- Add your partner as a collaborator to your copy of the
github-games
repository. - Clone your partner's repository to your local machine.
- Use
git clone URL repo-name
to give the repository a different name - Create a branch called
partner-instructions
in your partner's repo. - Add instructions for playing the game (beginning at line 7) to the README.md
- Push your branch to your partner's repo and open a pull request.
Step 2
After your partner has completed step 1:
- Go back to your copy of the game and merge the game-instructions branch in your own repo (you can use a pull request or do it locally).
- Go to the pull request your partner created and resolve any merge conflicts in your own repo.
Creating Atomic commits
- Why Atomic commits are important
- Making Changes
- Create a branch for
git checkout -b slow-down
- Change the timing for the game to speed it up or slow it down in index.html (line 78)
- Change location of texture.jpg to images/texture.jpg (line 9)
-
git status
-
mkdir images
-
git mv texture.jpg images/texture.jpg
-
git status
-
git add -p
and stage the change for the image location
- Create a branch for
- Viewing Local Diffs
- Comparing Local File States
-
git diff
-
git diff --staged
-
git diff HEAD
-
git diff --color-words
-
- Comparing Local File States
-
git commit
-
git status
-
git commit -am
How Commits are Made
- Show how commits are made and the impact it has on what we can do with our history.
Creating a Repository Locally
- Creating a Repository on the Command Line
-
git init practice-repo
-
ls -al
- Show
tree .git
directory - Show
cat .git/HEAD
- Show
cat .git/refs/heads/master
- Show objects directory (currently empty)
-
touch README.md
- Show
tree .git
again, still no objects -
git add README.md
- Show
tree .git
again, you now have 1 object, this is the blob -
git commit -m "Initializing the repo with a README"
- Show
tree .git
, now you have a tree object and a commit object - explain the importance of the root commit
-
- Use script to add files for reset activity (it is helpful to add this to the day 1 class repo):
-
Bash:
for d in {1..6}; do touch file$d.md; git add file$d.md; git commit -m "adding file $d"; done
-
PowerShell:
for ($d=1; $d -le 6;$d++) { touch file$d.md; git add file$d.md; git commit -m "adding file$d.md";}
Resetting History
- What happens when you reset - which trees are overwritten by each of the reset modes?
- Git reset modes - where the changes land
- Demo soft reset
- When is this commonly used?
- Demo mixed reset
- This is also the command we use to unstage files
- Demo hard reset
- Anything in your working directory or staging area will also be over-written - the only exception is the untracked files
Git reflog
- Show
git reflog
- Caveats of reflog
- Local only
- Temporary (90 days for reachable commits, 30 days for unreachable commits)
- Show
git cherry-pick
of single commit - Show
git reset --hard
back to where file 6 was originally created - Point out the effects of resetting forward on commit IDs
Rebase
- Set Up:
- Reset back to initial commit
- Create a branch
git checkout -b rebase-me
- Cherry-pick files 4-6 (out of order) onto the new branch
- Checkout to master
- Cherry-pick files 1-3 (in order) onto master
- Discuss Merge Strategies (if you haven't already)
- What type of merge is this? Recursive
- What if I want to do a fast forward? I would need to Rebase
- What happens when we Rebase
- Checkout to rebase-me branch
-
git rebase -i master
- Reorder files 4-6 on the branch
- Finish the rebase
- Merge
rebase-me
intomaster
Rebase with conflicts
- Create a new branch called
rebase-conflict
- On this branch
echo "This is some awesome content for file 4" >> file4.md
-
git checkout master
- On this branch
echo "File 4 already has some awesome content, but I like conflict" >> file4.md
-
git checkout rebase-conflict
-
git rebase master
- Now you will have a conflict, fix it just like you would a regular merge conflict (open the file, fix the conflicts, do a git add)
-
git status
-
git rebase --continue
Resets with Merge commits
- More complex resets
- Resetting when there is a merge commit involved
-
git reset --hard HEAD~^
-
git reset --hard HEAD~^2
- tells git to reset along the 2nd parent
Amending Commits
-
commit --amend
- Amends the commit at HEAD
- Show amending the commit message
- Show amending the commit content (anything in the staging area will be added to the last commit)
More fun with branches
- Oops, I forgot to create a branch
- Modify file before creating branch
- Show that the working directory and staging area are portable - files sitting in each area will remain there when you switch branches
- Modify file before creating branch
- Octopus Merges
- Create 2-3 branches off of master - on these files, add some .txt files to set up for the filter branch scenario
-
git checkout master
-
git merge branch1 branch2
- Git will merge all of these branches together
- Delete the extra branches
Filter branch
-
What is Filter branch? When is it used?
-
This is never something that is done lightly.
-
This is typically a conversation with your entire team.
-
One person makes the changes
-
They will need to push --force to update the remote
-
Everyone else will do a fresh clone of the repo
-
If you pushed your secrets to GitHub, get new secrets
-
Use filter-branch to remove the .txt files you added earlier
-
git filter-branch --tree-filter 'rm -f *.txt' HEAD
-
-
Show the back-up branch created by git
refs/original/refs/heads/master
-
After you have verified
master
-
git update-ref -d refs/original/refs/heads/master
-
git reflog expire --expire=now --all && git gc --prune=now
-
-
Show BFG Repo Cleaner and discuss the difference
Tags and Releases
- Introduce Tags
- What are they? Pointers to a specific commits
- Two types -a (annotated) and lightweight
- Using semantic versioning
- When to use Tags
- Difference between a tag (Git) and a release (GitHub)
- Create
git tag -a v1.0 SHA
-
git lol
to show tag pointer - Show how to view the tag and its contents
-
git show v1.0
- Show how to check out to tag
-
git checkout v1.0
- Explain detached head state, what does it mean?
- Show
cat .git/HEAD
- If you add commits here, what happens?
-
git checkout -b new-branch
- Show how to create a branch from a tag
-
git checkout -b new-branch v1.0
- Pushing tags
- Tags created locally are not automatically pushed
-
git push --tags
- Show how a tag is created on GitHub
Submodules
- Discuss the most common uses of Submodules
- Discuss better ways to accomplish dependencies
Add the submodule to the repository
- Use the repository for day 1, ask everyone to watch while you add the submodule to the repo
-
git submodule add https://github.com/githubtraining/example-submodule.git
- Show
git status
-
cat .gitmodules
-
tree .git
to show that the .git of the submodule has been added to the .git of the primary repo -
git diff --cached
to show the content ofexample-submodule
which should just be the sha of the current master in that branch - commit the submodule and push
Show the submodule on GitHub
- Point out the submodule in the repo
- Show the cross linking and SHA reference
Working with repo with Submodules
- Clone the repo to a new directory to demonstrate the following
- Ask the class to do a
git pull
- The submodule directory is there, but it doesn't have anything in it
-
git submodule init
-
git submodule update
- Can also do
git clone --recursive URL
to handle this during the clone - Or,
git submodule update --init
- now you can cd into the repo and see the contents
- Notice the detached head state - you can checkout to any version of the repo (e.g. a tag or another branch) and commit that change in the primary
Workflows for making changes in Submodules
- Git gives you the ability to make changes to submodules from within the parent repo.
- cd into the repo; note that you are still in a detached head state
- Create a branch
- Make and commit changes
-
git push --recurse-submodules=on-demand
Submodule Scripts
- We script a lot of the common submodules actions within our repository so people don't need to remember multiple steps
- Show example in
services-web
Scripts to rule them all
- Bootstrap scripts for submodules
-
git submodule sync --quiet --recursive
- Looks at the
.gitmodules
file and makes sure the URL listed for the submodule still matches what is in your local.git
. If not, it updates it. -
--recursive
tells Git to also update any nested submodules.
- Looks at the
-
git submodule update --init --recursive
- Clones missing submodules and pulls down the most recent changes. This would be the same as
cd
ing into the submodule and typinggit pull
. -
--init
also initializes any submodules that have not previously been initialized locally. In other words, it takes the information from.gitmodules
and uses it to create a home for the submodule in.git/modules
-
--recursive
tells Git to also update any nested submodules.
- Clones missing submodules and pulls down the most recent changes. This would be the same as
- Adding these scripts to the bootstrap or similar script ensures that tests or builds run against the repository are always working with the expected version of the submodule.
@brianamarie I think if we are going to try to have all of our training content in the manual format (which I believe we do) , we should include the advanced content in a book format.
I know this has been sitting here for a while - I would like to add these sections in the future, but am currently unsure of when I'll have the bandwidth to do this. I'll leave this issue open. If anyone else would like to start this off, please feel free. 😄
Adding on to this issue - it would be ✨ if we could have an additional script to run, which would open up several issues with more "advanced" topics. We could run this script in the case that we finish class early, or there are specific questions on these topics. The issues would have the instructions and some brief explanations for each concept.
An advantage of having these as issues rather than parts of the training manual is that it would easily allow us to sort during class based on interest. (ex: have people assign themselves to issues they're interested in.)
@brianamarie should this be in the programs backlog or should we hand this over to the implementation engineering team?
I think this makes sense to hand over to the implementation engineering team. 👍 cc @beardofedu @rwnfoo @allthedoll @aharshbe @ppremk @DGpeach - these are potential improvements to the training manual that I started when I was actively training. Let me know if you have any questions! Feel free to let this hang out here until a customer requests it, or incorporate it as preparation for an upcoming engagement. It would be really handy to have in the appendix for more advanced customers.
Dropping in some notes here about other potential additional content:
- Alternatives to filter-branch
- https://github.com/universeworkshops/deep-clean-your-git-repositories
- https://github.com/newren/git-filter-repo
- Team workflow activity
- In some cases, give participants access to
training-manual
, and help them get access - Configure GPG verification
- Create .gitignore files
- Show and try GUIs, like Git Kraken, GitHub Desktop
- Spend time on the post-tests together
- Go through the documentation section from GitHub for Non-Devs
- Create a slideshow on GitHub pages
- Create pull request and issue templates
- Configuring integrations
- Practice more with Learning Lab or Git Katas
This should also include subtree information, at the very least, comparing and contrasting the why and usability for subtrees and submodules.