Git Primer
- Concepts
- Configurations
- git merge
- Rebase
- git remote
- git commit
- best practice
- directories
- rerere
- git merge somebranch * and if it sees the same exact files it would just resolve them.
- presentation
- git log
- ls-files
- resources
Concepts
Concept | Description |
---|---|
Cache eq Index eq Staged | When you hear of cache index or staged all these are the same things. |
Cache eq Index eq Staged
Configurations
git config --system * => /etc/gitconfig
git config --global * => ~/.gitconfig or ~/.config/git/config
git config --local * => .git/config
https://dev.to/tomerbendavid/git-configurations-2ngi
git merge
git merge –abort
Command | Description |
---|---|
`git cherry-pick e43a6` | Take e43a6 and rebase into current branch |
Rebase
a way to integrate two branches instead of merge. instead of a branch - straight line, appends your commits to like the master branch.
git remote
command | description |
---|---|
`git remote show upstream` | Show remote branches |
`git checkout -b upstream1.3 upstream/1.3` | Checkout remote branch |
`git remote -vv` | Show branches remotes |
`git branch mybranch --set-upstream-to origin/branch_name` | update the remote of branch to origin |
git push
command | description |
---|---|
`git remote set-url origin https://someuser:somepass@github.com/someuser/test-node-sequelize.git` | git push userpass |
nothing in push? it’s only pushing the commits. control what is pushed, what is transmitted when we push.
git push
with no args would push all branches! so this is the default.-
git config --global push.default matching
this is the default match the local name to remote name and push all. - `git fconfig –global push.default nothing` - so you have specify explicitly what you want to push.
- `git config –global push.default current` push only the current branch. this is what i like.
- `git config –global push.default tracking` - but you have to set it before you create or pull the branch.
```
Branch to Github
git remote add github https://github.com/tomer-ben-david/nodejs-fullstack-boilerplate.git
git push -u github public
- Push only public branch into github.
multi master
```markdown setting has changed so that today will be simple push only current.
- we have multiple masters one from master one from upstream …
`git checkout somefeature` if it finds it on a only one remote it would check it out! because it knows determinsticly what the remote branch is. `git add remote github2 http://github..` so now you have all the branches twice in remotes.now it would not checkout because of ambiguity the branch is in both branches. the error will say you dont have such a branch because you have 2 of them. `git checkout -b myfeature -t github2/myfeature` => we explicitly say from which remote to check it out. now if you want to check it out from anohter remote you do `git checkout -b originmyfeature -t origin/myfeature` each branch points in the git configuration to which remote its pointing to. ```
git remote -v
git branch -r
show remote branches.
git pull
default merge
-
git pull –rebase
rebase instead. instead of two lines (2 branches) appends your commit to the master branch one straight line. So rebase is conceptually simulating that we take turns like concurrency we take turns on the master and not updating concurrently.
demo change two separate files. git push. one of them wont work. need to do git pull. then git push works. git show the graph and you will see that there are like separate lines that were merged. now doing instead `git pull –rebase`:
- imagine put aside my work.
- pull the master remote.
- and then stick my changes to the end.
so now we actually taking turns. if we need to resolve this, we resolve one continue to next etc. timestamps are irrelevant only the order of the tool git is not usung it its just human decoration. **huge advantage in linear history.**
- love the straight line!
-
git config branch.autosetuprebase always
always rebased indicator to what we want to do. git checkout branch will show that the default is rebase.
git commit
metadata
just strings, they could be wrong not credenhtials, commit message, author.
best practice
coarse grained
better to squash coars grained commits here is my feature, commits are self description to work.
directories
refs
pointers to commits, branches, tags, remotes.
rerere
```markdown **Reuse Recorded Resolution of conflicted merges**. Record that merge onflict and if you see it again reuse it. . if you solve a merge coflict do you go through the same thing when you need ot merge it to anoher branch? git helps with that with rerere. What’s its scope of what its recording?
create same file with different content in two different branches. push them. rememeber rerere is enabled. now if we do fetch now we do each pushed ot his own branch.
git merge origin/otherbranch * merge failed.
get rerere status * it’s saying that the files are being observed.
git rerere diff * it’s showng the diff conflict. and we merge the conflict with the text editor. save the file.
git status * showing both added the files.
git add .
git status * files modified ok.
git rerere status * still watchig the file. and it’s showing that the combination is memorizing the ocmbination.
git commit -m “rsoled” * recorded resolution for “file.txt” it’s storing it for 15 days or 60 days.
git rerere gc * will cleanup rerere all that are older than 15 days.
.git/rr-cache
cat .git/rr-cache/
git merge somebranch * and if it sees the same exact files it would just resolve them.
git commit * without a commit message. ```
git config rerere.enabled true
presentation
Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. git didnt’ achive the above.
a good progammer worries about data a bad programmer worries about code.
- aspect technical
- how to do brnching questions can be best practice its two kinds or political branching strategyt.
kv store
treat it as data
```bash cd .git/objects find . -name -type f | wc -l
objects are: blogs, trees, commits, tag ```
-
objects
-
set key
```bash echo ‘test content’ | git hash-object -w –stdin
if you set multiple times it will not delete the hash it will add new objects. if you delete locally the file you can get it back each version by git cat-file the hashes. ```
-
echo ‘test content’ git hash-object -w –stdin
-
-
get key
```bash git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
tree fb1cf9738e80e62cacd7cac8e795afd38e5ce868 parent 0f9fc521c2593733c9413e0061e4586120e63393 author someuthor tsomemail 1519288832 +0200 committer someauthor somemail 1519288832 +0200
TMSCSSC-1828 ```
-
-
tree
can contain subtrees. correlates objects to filenames.
-
filenames
-
group of files
-
like directory
-
git cat-file -p mastertree
print the latest commit of tree pointer to latest tree.
-
filename to object
-
git update-index –add new.txt
add file to index
-
git update-index –add –cacheinfo 100644 d670460b4b4aece5915caf5c68d12f560a9fe3e4 myfile.txt
add to index the object
-
git write-tree
✗ git write-tree d936f53d6a3450e681f4d6948394c9a7d8396f42
create a new tree from our current index. each such write-tree create a new snapshot so we have a new snapshot of our data.
-
git cat-file -p d936f53d6a3450e681f4d6948394c9a7d8396f42
print the tree that was written
-
-
subdirectory
or load subtree into index
-
read subtree into index
-
git read-tree –prefix=bak skfj0jlsjflskfjjsh
now bak is a subtree for the tree we read and added the tree. each git
-
git write-tree
-
-
-
-
see all objects
-
find .git/objects -type f
note that we see both blobs trees and commits.
-
-
commit object
this is information about the commit this is how you spefcify the commit message it is a commit object. for demo we can now add commit messages to the other commits, AMAZINg we have just made commits without using any of the git commands.!
-
echo “commit message” git commit-tree 92834928 here we add a comimt message to the tree with hash 928… and git will automatically add the author timestamp and email info to this commit tree hash. you can view it with `git cat-file -p 92834…`
-
-
tag object
-
tagger
-
date
-
message
-
pointer
-
usage
usually points to a commit and not to a tree.
```bash git update-ref refs/tags/v1.0 sjkdfhsofw * => lightweight tag. reference never moves. git tag -a v1.1 lasjflkajsfksj -m “test tag’ *=> annotated tag, git creates a tag object and writes a reference to point to it. cat .git/refs/tags/v1.1 slkajsflkajsfdklj git cat-file -p alskdfjlaskfj * => will show that its a pointer to a commit. you can tag any git object doesnt have to be a commit. ```
-
-
remotes
-
refs/remotes
remotes are different from branches (refs/heads) in that they are read only you never update a remote ref with commit command only git this is the last known state pointer of the remote.
-
-
packfile
```markdown
- update a fiile
- commit
- you will see a different hash. we still have the previous hash.
so we are wasting space we have 2 blobs. git can pack it from time to time so stored in the same object with the diff.
call git gc for initiating pack. ```
-
git gc
also when pushing to a remote then git performs gc.
-
pack-hash.idx
pack of the index, the current index content.
-
pack-hash.pack
pack of all the objects that were removed.
-
git verify-pack
in order to view the content of pack `git verify-pack -v .git/objects/pack/pack-hash…idx
-
refspec
```bash git remote add origin https://github.com/myuser/somethinggit
cat .git/config [remote “origin”] url = https://github.com/myuser/somethinggit fetch = +refs/heads/*:refs/remotes/origin/* * => refspec
: so will take references from remote heads to local dir to refs/remotes/origin - * => update the reference even if it isn’t a fast forward.
you can access log of remote branch using local target of the refspec like this: all the below are equivalent. git expands all of them to refs/remotes/origin/master
git log origin/master git log remotes/origin/master git log refs/remotes/origin/master ```
references
instead of remembering keys, let’s have references to some special keys, like the HEAD whcih simply points to a sha1 key
-
master
create a reference to latest commit:
```bash echo 123oihskfh293 > .git/refs/heads/master git log –pretty=oneline master ```
and to more safely update a ref: `git update-ref refs/heads/test cacacaj83`
-
branch
when you do `git branch mybranch` how does it know from where to branch? it’s from the HEAD which points to the latest commit.
-
HEAD
HEAD is symbolic reference to the branch we are currently on it does not contain a SHA1 it’s a pointer to a reference. HEAD content: refs/heads/mybranch
-
@
Head is also known as “@” you can use @ whenever you need head
-
git checkout @{-1}
git checkout @ is HEAD then go to the last place (-1) of the HEAD meaning the last branch that HEAD pointed to.
-
maintenance recovery
if you do `git reset –hard skfjhskfdhj` and thus you go back and loose a commit you can do `git reflog;git log -g` and then `git checkout to an older commit`
git log
git log –oneline –decorate –graph –all
ls-files
git ls-files –stage
Show staged files.
resources
http://ohshitgit.com
https://github.com/k88hudson/git-flight-rules