Using GIT Subversioning Effectively Sachin Gupta, 18-Feb-2017, 21 mins , webdev , versioning , git , common tasks , overview , walkthrough , command reference , noteablesA very simple post for Practical Git Repositories. Here I’ll add details about Git Commands for common tasks with Git like Cloning a Repository. Also there is short and precise overview of GIT functioning and commands. **Table Of Contents** [TOCM] ### Where is Git Documentation ? You need to use [Getting Started with Git](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control) guide over internet. ### Git Operation - The Big Picture This is a quick chart to understand GIT Working, its created after reading a nice artice on [Reset & Squashing Demistified](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified#_git_reset) and [Undoing Things](https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things) Note: 1. **HEAD:** Head is termed as *Snapshot of Last Commit (Next Parent)* in local repository 2. **INDEX:** Index or Staging is termed as *Proposed Next Commit Snapshot* Diagram: ```seq participant Working\nDirectory participant Index\n(Staging) participant HEAD\n(Local Repo) participant GIT SERVER\n(Remote GitLab) Working\nDirectory->Index\n(Staging): Stage Files\n(*git add*) Index\n(Staging)->HEAD\n(Local Repo): Commit Files\n(*git commit*) Working\nDirectory-->Index\n(Staging): Add File Or Amend Comment\n(*git add newfile*, *git commit --amend*) Index\n(Staging)-->Working\nDirectory: UnStage File\n(*git reset HEAD <file>...*) HEAD\n(Local Repo)->Working\nDirectory: Checkout Files\n(*git checkout*) HEAD\n(Local Repo)->Working\nDirectory: Revert File\n(*git checkout -- <file>*) Working\nDirectory-->HEAD\n(Local Repo): WD Modified & Deleted\n(*git status*) Working\nDirectory-->Index\n(Staging): WD Untracked - Not Added Files\n(*git status*) HEAD\n(Local Repo)->GIT SERVER\n(Remote GitLab): Sync. Repos.\n(*git push/pull/fetch*) HEAD\n(Local Repo)-->GIT SERVER\n(Remote GitLab): HEAD UnSynched or Not Pushed\n(*git status*) ``` []()Diagram: GIT Operations Overview, Must See [Git Reset Demistified](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified#_git_reset) ### Git Reset Functions Lets remeber this figure: ![IMAGE NOT FOUND](https://git-scm.com/book/en/v2/images/reset-start.png) []()Courtsey [https://git-scm.com](https://git-scm.com) for image above #### 1. Revert HEAD to Old Commit This is equivalent to move HEAD to old commit, discarging all commits above requested from local repository. *Note:-* After `git reset`, index/staging will contain difference of files from reverted-commit to repostitory max (*files are not unstaged*). ##### A. git reset [revision] `git reset 9e5e6a4` will move HEAD & MASTER back to revision `#9e5e6a4`. This is used when you want to **revert back local repository to some earlier committed revision** dropping all bad commits above (*in this case above #9e5e6a4*). Here `--mixed` is implied. ##### B. git reset --soft [revision] Similarly, `git reset --soft HEAD~` will revert to revision which is `HEAD~` or `Parent of HEAD`. Here `~` represents `parent-of`. This is equivalent to reveting last commit. When we `reset` branch HEAD is moved back, **without changing Index and Working Directory**. Now you can make changes to working directory files, unstage files and revert files to 9e5e6a4 (*by git checkout*) and then use `git commit` to create fresh commit above `9e5e6a4`. This is just like what `git commit --amend` would have done , means **reverting repostiory back to old revision and recommitting new commit with correct changes** #### 2. Revert HEAD & UnStage Changes This is equivalent to move HEAD to old commit, discarging all commits above requested from local repository and Unstaging all difference of files from reverted-commit to repostitory max (*files are unstaged to working directory*). You can revert these files (*using git checkout*) or freely edit them and add to stage using *git commit* for next commit action. ##### A. git reset --mixed [revision] If we use `git reset --mixed 38eb946` command, Here `--mixed` option will revert HEAD to `#38eb946` as well as **unstage difference to repository-max in working directory**. *This is default action*. Now use `git add or edit`, `git commit`, then `git push` to create new revision discrding all revision above `#38eb946`. #### 3. Revert HEAD, UnStage Changes, Revert WorkDirectory This is equivalent to move HEAD to old commit, discarging all commits above requested from local repository and Unstaging all difference of files from reverted-commit to repostitory max and reverting (*checkout*) all UnStaged files from Working Directory. Thus all HEAD, INDEX & WRKDIR points to same revision requested for like `#38eb946`. WRKDIR may still contain new files (*also called untracked files*) which can be reverted using cleanup. ##### A. git reset --hard [revision] If we use `git reset --hard 38eb946` command, Here `--hard` option will revert HEAD to `#38eb946` as well as **unstage difference to repository-max in working directory**, then revert *unstaged files to files in #38eb946* in working directory. Now use `git add or edit`, `git commit`, then `git push` to create new revision discrding all revision above `#38eb946`. Also use `git clenaup` to **revert any untracked or new file** still in your working directory. #### 4. Reset Files in Staging (To HEAD) ##### A. git reset [file] If we use `git reset file.txt` with HEAD at `#38eb946 (file.txt v1)` and both stage & work directory at `file.txt v2`. This will replace `file.txt v2` in staging with `file.txt v1 in HEAD(#38eb946)` #### 5. Reset Files in Staging (To OTHER REVISION) ##### A. git reset [revision] -- [file] If we use `git reset eb43214 -- file.txt`, this will replace `file.txt v2` in staging with `file.txt vK` in some commit `#eb43214`. HEAD will still be at `#38eb946 (file.txt v1)` and working directory be at `file.txt v2`. #### Summary Of Reset Functions | | HEAD | Index | WorkDir | WD Safe ? | | :---- | :---- | :---- | :---- | :---- | | **Commit Level** | | | | | | `git reset [commit]` | REF | YES | NO | YES | | `git reset --soft [commit]` | REF | NO | NO | YES | | `git reset --mixed [commit]` | REF | YES | NO | YES | | `git reset --hard [commit]` | REF | YES | YES | **NO** | | `git checkout [commit]` | HEAD | YES | YES | YES | | **File Level** | | | | | | `git reset [commit] [file]` | NO | YES | NO | YES | | `git checkout [commit] [file]` | NO | YES | YES | **NO** | *Notes:* 1. The “HEAD” column reads “REF” if that command moves the reference (of branch) that HEAD points to, and “HEAD” if it moves HEAD itself. 2. The “Index” column reads “YES” if its updated else “NO”, Same with “WorkDir” column. Note that `git reset [commit]` and `--mixed` are same as default action is mixed. 3. Pay especial attention to the WD Safe? column – if it says NO, take a second to think before running that command. ### Git Squashing Functions Lets remeber this figure: ![IMAGE NOT FOUND](https://git-scm.com/book/en/v2/images/reset-squash-r1.png) []()Courtsey [https://git-scm.com](https://git-scm.com) for image above Say you have a series of commits with messages like “oops.”, “WIP” and “forgot this file”. These are shown in figure above. And lets say **you want to merge all commits as single commit before pushing it to server** giving it a meaninful comment like `Bug Fixation: Issue - 12FESQW` In order to achive this first take HEAD back to point from which you want to squash using `git reset --soft HEAD~2` or `git reset --soft eb43bf8`. Note that use of `--soft` will **only move head and keeps differences in staging as well as working directory**. Now use `git commit` again with new message `Bug Fixation: Issue - 12FESQW`. Thus squashing is equivalent to `soft reset followed with git commit`. Use `git push` in case you want to sync to a remote server. ### Cloning A Git Repo Often you would like to clone (*or duplicate*) a git repo instead of mirror (*with live sync*). It's just like creating a folder copy at the begning and start working afresh. To do that code follows: ```bash # Create a scratch directory and move to it mkdir scratch cd scratch # Bare clone your repository (this command copies repostiry itself with folders like hooks etc.) # Once this command completes you'll find a folder ./source-repository.git git clone --bare https://github.com/username/source-repository.git # First manually create a `new-repository` on your server and do a Mirror Push cd source-repository.git git push --mirror https://github.com/exampleuser/new-repository.git # Delete all temporary directories from the HDD cd .. rm -rf source-repository.git cd .. rm -rf scratch ``` ### Undo Last Commit Often, you could've pushed unnecessary files into a git repository, which needs to be undone. #### Using TortoiseGit If you need to revert back to the previous state before the last commit just select the commited action from the log list and select `revert changes by this commit`. Take care, you need to `commit` and `push` again the changes made. #### Using Command Line **Yet to add** ### Ameding Last Commit #### Add Files to Commit or Modify Commit Message One of the common undos takes place when you *possibly forget to add some files to commit*, or you *mess up your commit message*. And now you want to **add extra files or change comment of last commit*. You can use commit with the `--amend` option: ```bash $ git commit --amend ``` This command takes your staging area and uses it for the commit. If you’ve made no changes since your last commit (for instance, you run this command immediately after your previous commit), then your snapshot will look exactly the same, and all you’ll change is your commit message. As an example, if you commit and then realize you forgot to stage the changes in a file you wanted to add to this commit, you can do something like this: ```bash #Commit with missing forgotten_file $ git commit -m 'initial commit' #Add forgotten_file to staging area $ git add forgotten_file #Amend last commit (HEAD) with forgotten_file $ git commit --amend ``` You end up with a single commit – **the second commit replaces the results of the first**. #### Unstaging a Staged File (Remove File from Commit) For example, let’s say *you’ve changed two files and want to commit them as two separate changes*, but you accidentally type git add * and stage them both. The `git status` command reminds you: ```bash #Accidently added all files to staging area $ git add * #Shows two files README.md and undesired CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) renamed: README.md -> README modified: CONTRIBUTING.md #Unstage not required CONTRIBUTING.md $ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md ``` You've to use `git reset HEAD ...` command to UnStage or remove a file from Staging area of commit. This is as shown: ```bash #Removing file from staging area $ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md #Checking file status in staging and working directory $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: CONTRIBUTING.md ``` The CONTRIBUTING.md file is modified but once again unstaged. #### Unmodifying a Modified File (Revert File) What if you realize that you don’t want to keep your changes to the CONTRIBUTING.md file?. Luckily, `git status` tells you how to do that, too. In the last example output, the unstaged area looks like this: ```bash #Shown one file (README.md) in staging and ( CONTRIBUTING.md) bought back to Working Directory $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: CONTRIBUTING.md ``` Use `git checkout -- ...` to discard changes in working directory in this case `git checkout -- CONTRIBUTING.md` as shown: ```bash #Revert ( CONTRIBUTING.md) bought back to Working Directory $ git checkout -- CONTRIBUTING.md #Check status, only shows one file (README.md) in staging for commit and push. $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) renamed: README.md -> README ``` . </textarea> </div> « OlderRelatedComments» Newer Related PostsUsing Docker EffectivelyHashiCorp: Packer, Terraform, Serf, Consul, VagrantDocker: Get Your Hands Dirty With AdministrationREST Protocol, Test Tools & HTTP Command StructureRancherOS Getting Started GuidePlease enable JavaScript to view the comments powered by Disqus.