---
# System prepended metadata

title: Git
tags: [learning]

---

---
title: Git 
tags: learning
---

## Avi


#### Resources:

- Cool interactive web app to learn Git: https://learngitbranching.js.org/?locale=en_US 

### Topics:
#### At most of the places where we have used branch refernces, we can use relative references! 
#### git branch 
- `git branch b1` creates branch ar current HEAD 
- `git checkout -b b1` creates branch at current HEAD and HEAD points to that branch
- `git checkout -b b1 c1` creates branch at c1 and HEAD points to that branch
    #### reassign
    - If the branch is already created, we can reassign it by, 
    - `git branch -f b1 dest` where dest is the pointer where you want to reassign it
    - few examples, `git branch -f master bugFix`, `git branch -f HEAD^3`
    #### git reset
    - While previous block helps you move around branch references, here we'll able to do reset in branch
    - reset is basically rewriting history of commits
    - `c0 <-- c1 <-- c2(master*)`, `git reset c0` will result in `c0(master*)`
    #### git revert
    - reset might look amazing for undos, revert is something where you can keep the changes you have made, and still can go to the commit you want, let me give you example
    - `c0 <-- c1 <-- c2(master*)`, `git revert c0` will result in `c0 <-- c1 <-- c2 <-- c0'(master*)` 
#### git merge
- whenever you merge two branches, it will create a new commit.
- if you're on master, `git merge b1` will create new commit and master will be on that commit 
- you can go back to b1, `git merge master` will bring b1 to new commit 
#### git rebase
- `c0 <-- c1 (master)`
- `c0 <-- c2 (feat1*)`
- you completed working on your feature on feat1 branch, and you're sure to push changes to master, go to feat1, `git rebase master`
- result of above `c0 <-- c1(master) <-- c2' (feat1*)`
- now go to master, `git rebase feat1`
- result of above `c0 <-- c1 <-- c2' (feat1, master*)`
- Just for example, `c0(master) <-- c1 <-- c2 <-- c3(feat*)`
- `git rebase master` won't make any difference as you're up to date with master
- BUT, if you're not okay with ordering `c1 c2 c3`, you can do `git rebase -i master` or `git rebase HEAD~3` (will open prompt box to organize commits)

#### Relative References 
- `^#` where # represents any number, if not given it will be 1
- `HEAD^` means HEAD's parent
- `HEAD^2` means will take it to HEAD's second parent
    - example, `c0 <-- c2(*)` and `c1 <-- c2(*)` 
    - then, `HEAD^2` means c1
- `~#` where # represents any number, if not given it will be 1
    - `HEAD~` means HEAD's parent
    - `HEAD~2` means HEAD's grand parent

#### git cherry-pick
- From your HEAD, whenever you want specific commits to be in particular order you can use it `git cherry-pick <ref> <ref> ...`
- NOTE : Remember that git cherry-pick will plop down a commit from anywhere in the tree onto HEAD (as long as that commit isn't an ancestor of HEAD). Even siblings are allowed, just not Ancestor
- `c0 <-- c4(master*) <-- c1 <-- c2(bug1)`
- `c0 <-- c4(master*) <-- c3(bug2)`
- `git cherry-pick c2 c3` will result in 
- `c0 <-- c4 <-- c2' <-- c3'(master*)`
- `c0 <-- c4 <-- c1 <-- c2(bug1)`
- `c0 <-- c4 <-- c3(bug2)`
#### git tag
- to permanently mark historical points in your project's history. For things like major releases and big merges, tags are used
- `git tag t <ref>`
- `git tag t1 HEAD~2` or `git tag t2 master` or `git tag t3 c2`
#### git describe
- `git describe <ref>` will give `<tag>_<numCommits>_g<hash>` Where tag is the closest ancestor tag in history, numCommits is how many commits away that tag is, and <hash> is the hash of the commit being described.

<br>


## Poojan

#### Topics:
- `git stash`:
    - ...

- `git merge`
    - `git-merge` - Join two or more development histories together
    - when doing so there might be a merge conflict. When more than one person change same line of code. Here is the simple exaple: https://github.com/nruth/git-conflict-resolution-demo
    - You need to manually resolve any merge conflict that happens in file. These merge conflicts are indicated by `<<<<<<`, `======`, `>>>>>>`.
    - The part starting from `<<<<<<` till `======` is your current branch changes. And part from `======` to `>>>>>>` is the other branch code. Beside `<<<<<<` its written `HEAD` that means your current branch where `HEAD` is pointing to. And besid `>>>>>>` its written your other branch name. Note you might notice something like `||||||` which represent common ancestor in `diff3` merge conflict style.
 
#### Random things:
- How do you check where `HEAD` is pointing in currently?
    - `git log -1`
    - `git rev-parse HEAD`
 
- git `HEAD` detached mode?
    - https://howtogit.archive.pieterdedecker.be/recipes/getting-out-of-detached-head-state.html
    - https://stackoverflow.com/questions/5772192/how-can-i-reconcile-detached-head-with-master-origin
    - `HEAD` is always pointing to a branch but when its pointing to a commit which is not part of any branch's current history `HEAD` will be in detached mode.
    
- `git reflog`:
    - `git log` vs `git reflog`? (https://stackoverflow.com/questions/17857723/whats-the-difference-between-git-reflog-and-log)

- `HEAD~` vs `HEAD^` vs `HEAD@{1}`?
    - https://stackoverflow.com/questions/26785118/head-vs-head-vs-head-also-known-as-tilde-vs-caret-vs-at-sign/26785200
- `rebase` or `merge`?
    - https://www.atlassian.com/git/articles/git-team-workflows-merge-or-rebase
    
- How to pull a specific branch from remote?: https://stackoverflow.com/questions/1709177/git-pull-a-certain-branch-from-github  
     ```
     git branch -f remote_branch_name origin/remote_branch_name
     git checkout remote_branch_name
     ```
- Your git clone taking too much time. And you dont care about all the previous commits just want the latest repo? Consider looking into `git clone --depth` option. 
    - https://linuxhint.com/git-shallow-clone-and-clone-depth/
    - Ex: git clone url --depth 1
        - this will give you the only one last commit.

