Permalink
Browse files

init

  • Loading branch information...
Axylos
Axylos committed Nov 13, 2017
0 parents commit 1146279f89be43da80859f4067afb33914fae786
Showing with 301 additions and 0 deletions.
  1. +165 −0 README.md
  2. +135 −0 cheatsheet.md
  3. BIN imgs/cleanup.jpg
  4. BIN imgs/junio.jpg
  5. BIN imgs/shalt_not.jpg
  6. +1 −0 local_lab.md
165 README.md
@@ -0,0 +1,165 @@
# Group Git

### Objectives
*After this lesson students will be able to*
- Describe the different layers of the data model git exposes to the user
- Explain basic git commands in terms of this model, e.g., commit, add, log
- Safely work on a feature branch and merge it back to the master branch
- Be aware of a few pitfalls when working with git in a Group

### Review
First, let's call to mind some of the `git` commands we've already seen.

What does each one do? Are there similarities in basic functionality and code/objects handled by each command?

### The Golden Rule

*__Don't change what's been shared__*

![shalt_not](imgs/shalt_not.jpg)

It's not the end of the world if it happens, but it's on you to make the world right

![cleanup](imgs/cleanup.jpg)

We'll fill in the gaps as we go, but if you remember anything from this lecture it should be these maxims.

- Do not (accidentally) change committed history that has been pushed to `origin`

- If you do, make sure to either undo the change or ensure that all team members have a consistent history before proceeding

### Git's Data Model for Users

![junio](imgs/junio.jpg)

Thank the guy on the right, but don't forget the guy on the left.

*From wikipedia*
> Torvalds cited an example of a source-control management system needing 30 seconds to apply a patch and update all associated metadata, and noted that this would not scale to the needs of Linux kernel development, where syncing with fellow maintainers could require 250 such actions at once. For his design criteria, he specified that patching should take no more than three seconds, and added three more points:
> Take Concurrent Versions System (CVS) as an example of what not to do; if in doubt, make the exact opposite decision
> Support a distributed, BitKeeper-like workflow
> Include very strong safeguards against corruption, either accidental or malicious
> The development of Git began on 3 April 2005. Torvalds announced the project on 6 April; it became self-hosting as of 7 April. The first merge of multiple branches took place on 18 April. Torvalds achieved his performance goals; on 29 April, the nascent Git was benchmarked recording patches to the Linux kernel tree at the rate of 6.7 patches per second. On 16 June Git managed the kernel 2.6.12 release.
> Torvalds turned over maintenance on 26 July 2005 to Junio Hamano, a major contributor to the project. Hamano was responsible for the 1.0 release on 21 December 2005, and remains the project's maintainer.
Data Layer | Description
---- | ----
Working Directory | Local file system (your computer's files like normal)
Staging Area | Changes that have been `add`ed and are ready to commit
History | Changes that have been committed in a series of commits uniquely identified by a `SHA1` hash
Remote | An associated version of the repository on a remote host accessible via networking
Reflog | All branch checkouts, stashes, and commits, as well as other events in the repo *within about the past month*
Stash | Changes that have been `stashed` and can be retrieved later, similar to a stack of pseudo-commits

The first three layers are ones we've seen before. The working directory is the normal files on your machine; the staging area are files that will be included in the next commit; history denotes all committed changes.

We've also been working with `remote`s when cloning/pushing from github.

The other two layers are utility areas that git exposes, mostly as a view into its inner workings and as a hail-mary toolkit when things get rough or when a quick and dirty transition is helpful. Generally speaking, the `reflog` should not be trusted as a reliable layer to work with and is mostly there to get you out of a jam; the `stash` can be used for quickly stowing away a few simple changes and getting them back later.

### Git Command Review

Now let's go over some `git` commands in light of this data model. Each command will typically either be used to inspect the changes at a particular layer(s) or it will transition a set of changes from one layer to another.

Command | Function | Data Layer(s)
----- | ----- | -----
add | move changes | WD -> Staging
commit | move changes | Staging -> History
status | inspect changes | WD/Staging/History (via what commit is the last one)
show | inspect changes | WD/History (if `SHA1` is given)
branch | inspect | WD/History (via what branch is current)
diff | inspect changes | WD<-->History (by default other possibilities exist but this is the main one)
log | inspect | History
push | move changes/sync | Local History -> Remote History
pull | move changes/sync | Remote History -> Local History/WD/Current Branch
fetch | move changes/sync | Local History -> Local History(background)
checkout | move index | WD (moves WD reference to a different HEAD of History)
merge | move changes | applies new changes from one branch to the HEAD of the current branch
rebase | move changes | applies changes from a different branch's history underneath the current branch's history
reset | un-set changes | History -> Staging/WD/Null depending on what flag is set

### __Zoinks__

Let's look at an example and outline the steps up to committing and pushing to origin:

#### (I Do): Feature Branching + Merging

#### Main branch
- Init repo
- Touch `hello.js`
- write `helloWorld()`
- Add the changes
- Commit
- Create remote
- Push to origin

What story can we tell using the model of git's data layers from above?

#### Feature Branch
- `checkout -b` bye
- Write `bye()` in `bye.js`
- Commit
- Add `convo.js`
- Commit + run
- `checkout` master + fix
- `checkout` bye + merge changes from master
- `checkout` master and merge in `bye`

#### Conflict Resolution
- `touch` stringly.js
- `checkout -b` toUpper
- add `function toUpper()` + commit
- `checkout -b` toLower + commit
- add `function toLower()`
- Merge both back into `master`
- Resolve conflict

### (You Do) Local Conflict Resolution
Go [here](local_lab.md) and follow the instructions

- Init a new repository
- Make an `init` commit before making any changes
- Add a file `index.js` with very skeletal html, i.e., just an opening and closing `html` tag, `head`, and `body`
- Commit
- Create a new repo on github
- Add remote origin to your local repo
- Push to origin

What story could we tell in light of the data model described above? What commands could we use to inspect the work we've done so far?

We can inspect the changes on origin by prefacing a branch or `SHA1` with `origin/`. Try it with `show` or `log`

__NOTE:__ `git log --oneline --decorate --graph --all` is your friend

#### Feature Branches

As a project grows, it can help substantially to break out sets of changes into their own branches which are subsequently merged back in to the `master` branch. As you know, these branches can also be pushed to github.

Let's check out two feature branches and merge them back in to master

- `git checkout -b nav`
- Add a few commits to make a nav
- `git checkout master`; `git checkout -b main`
- Add a few commits to make a main container
- `git checkout master`
- How can we view all of the changes we've just made and their relation to one another?
- `git merge nav`
- Inspect history and the current branch at this point
- `git merge main`
- What happened? How do we get back on track?

## Extra Resources
- [An Incredible Git Tutorial](http://gitimmersion.com/) probably the second most helpful git thing I've ever come across . . .by our friend `Jim Weirich`

- [a nice set of cheat sheets](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) from Atlassian

- [A more in depth and practical look at git rebase](https://dev.to/maxwell_dev/the-git-rebase-introduction-i-wish-id-had) Helpful to strengthen your rebase sorcery

- [Linus Torvalds nerding out about git](https://www.youtube.com/watch?v=4XpnKHJAok8) Buckle up

- [Obligatory Junio Hamano interview](https://www.youtube.com/watch?v=qs_xS1Y6nGc)
@@ -0,0 +1,135 @@
## Figuring where you at

* [`git log`](https://git-scm.com/docs/git-log) - show all commits
* [`git branch`](https://git-scm.com/docs/git-branch) - shows current branch
* [`git status`](https://git-scm.com/docs/git-status) - show files with changes
- `git st` is a common alias

## Looking at changes

* [`git diff`](https://git-scm.com/docs/git-diff) - the diff since last commit
* `git diff SOMESHA` - the diff since `SOMESHA`
* `git diff BRANCH-NAME` - the diff from another branch
* [`git show`](https://git-scm.com/docs/git-show) - show the diff of last commit
* `git show SOMESHA` - show the diff of `SOMESHA`

## Staging changes

Use [`git add`](https://git-scm.com/docs/git-add)

* `git add -A`/`git add .`/`git add -a`
- Don't use these. (except maybe your first commit)
* `git add FILENAME_OR_DIR`, this is better
* `git add -p`
- stages in _hunks_
- allows you to see each line of diff while deciding what to include
* [`git reset`](https://git-scm.com/docs/git-reset) to un-stage your changes

## Committing changes

If you have staged your changed properly all you need is
* [`git commit`](https://git-scm.com/docs/git-commit)
- ex `git commit -m 'add person.js'`
- use **present tense** for your messages
* `git commit --amend` to add to previous commit
- Use this if you forgot to add something to your last commit
- If you have pushed before doing this, you will need force-push

## Pulling

* [`git fetch`](https://git-scm.com/docs/git-fetch) - don't use this
- gets the changes of a branch/branches
* [`git pull`](https://git-scm.com/docs/git-pull) - use this
- gets the changes _and_ updates your branches accordingly

## Pushing

Use [`git push`](https://git-scm.com/docs/git-push)

* `git push origin BRANCH-NAME`
* `git pushf origin BRANCH-NAME`
- add the alias `pushf = push --force-with-lease` to `.gitconfig` if you don't have it
- Never `pushf` if you don't need to
- Always make sure you know what you are overriding! `git diff origin/BRANCH-NAME`


## Debugging history

One of the many great things about `git` is it makes diagnosing issues easy.

Check these out !!

* [`git blame`](https://git-scm.com/docs/git-blame)
- `git blame FILENAME` - see history of file chages
- add alias `praise = blame` for positivity!
* [`git bisect`](https://git-scm.com/docs/git-bisect)
- This is effectively a _binary search_ to find a commit that broke something



## Checking out branches

Use [`git checkout`](https://git-scm.com/docs/git-checkout)

* `git checkout BRANCH-NAME`
* `git checkout -` go back to last branch
* `git co` is a common alias


## Merging and rebasing branches

### merging

[`git merge`](https://git-scm.com/docs/git-merge)

Typically branches, should be _merged_ into master. **This should be done from Github**. Merging takes every commit and along with a merge-commit from the branch and adds that to the target branch (usually `master`)

**Ex**: From `master`: `git merge BRANCH-NAME` takes all the commits from `BRANCH-NAME` and a merge-commit and adds those to master.


### rebasing

[`git rebase`](https://git-scm.com/docs/git-rebase)

Rebasing rewrites history. This adds the commits from another branch and puts your commits on top of your branch. (Actually it puts _new copies_ of your commits on top). Typically, we rebase `master` from another branch. This does not add an extra merge-commit.

**Ex**: From some branch: `git rebase master` will take anything that was added to master since branched off (or last rebased) and put those commits _before yours_. Your commits are then added on top of your branch.


## Adding a feature

* Do NOT commit directly to master
* Check out a branch from master `git checkout my-new-feature`
- where `my-new-feature` is the branch name
* Add your code and commit `git commit -m 'add my new feature'`
* Push your branch to GitHub `git push origin my-new-feature`
* Make a PR on GitHub
* Review the changes
* Make requested updates, commit again
* Merge PR into master from github

## If there are conflicts

* From the new branch, `git rebase master`
* You will see an error like `CONFLICT (content): Merge conflict in FILENAME`
* Manually resolve the conflicts. Use your human mind.
- Git cannot tell you what to do here. Figure out what changed since you branched off of master
- What is the goal of your changes? Why did they touch the same or adjacent lines?
* Once the conflicts are resolved:
- `git add FILENAME`, `git rebase --continue`
* If there are more conflicts, you must resolve those too
* Finally you can push the rebased branch back up to github `git pushf origin my-new-feature`
* You will have to force-push since you are re-writing history
* Now you should be able to merge from github
* If you mess up the rebase along the way you can always `git rebase --abort` and start over


## Things to remember

To make sure you don't lose your work always keep these things in mind

* Commit often - keep your commits small
* Push often - once every few commits
* Look at the diff from origin before force-pushing
* Do not push to master. Make a PR
* **Look at [the docs](https://git-scm.com/docs/)**. Do not just copy-paste from Stack Overflow without knowing what it does
BIN +193 KB imgs/cleanup.jpg
Binary file not shown.
BIN +73.1 KB imgs/junio.jpg
Binary file not shown.
BIN +429 KB imgs/shalt_not.jpg
Binary file not shown.
@@ -0,0 +1 @@
hey there

0 comments on commit 1146279

Please sign in to comment.