Skip to content

Instantly share code, notes, and snippets.

@phamducminh
Last active August 27, 2022 12:32
Show Gist options
  • Save phamducminh/10d794e2cf382e13dfa863467da29fcc to your computer and use it in GitHub Desktop.
Save phamducminh/10d794e2cf382e13dfa863467da29fcc to your computer and use it in GitHub Desktop.
Git Tutorial

Git Tutorial

The purpose of this document is to guide the user on how to work with the Android git repository and git commands in general. This document is not meant to be a full git teaching tool, but more of a getting started guide.

By Minh Pham, 2020

Content


Clone the root repository

Clone the base repository

$ git clone

NOTE: If your repository uses submodule then call

$ git submodule init
$ git submodule update

Or add –recursive when you clone your repo

$ git clone --recursive

The first time you clone repo, you will be asked to enter username and password. If you want to remember it so that you don't have to type user/pass every time you fetch or push commit to the repo. Then typing this command:

$ git config credential.helper 'cache --timeout=300'

with 300 is the caching time in the second unit. I recommend you type 31536000

Checkout specific branch

To checkout one arbitrary branch on remote, use command:

git fetch --progress --recurse-submodules=no origin +refs/heads/:refs/remotes/origin/

Change remote URL

To change remote URL:

git remote set-url origin https://abc.xyz/xuyennt/project-android.git

Configure user information

The first thing we must do is set our user information. This information will be attached to each of your commits to the remote repositories. This is what we will use to track changes on a per user basis. Run the following commands from the terminal prompt (Mac/Linux) or Git Bash shell (Windows):

$ git config --global user.name “name”
$ git config --global user.email email@vng.com.vn

For example:

$ git config --global user.name "Minh Pham"
$ git config --global user.email minhpd@vng.com.vn
  • Note: the param --global will apply user name and email for all git repositories on your local machine. If you only want to apply current repo, just replace it with param -local.

Switching between local branches

Each local branch is stored locally on your system. The files are all stored once, and their deltas and managed between each other which makes switching between branches pretty quick.

NOTE: You will not be able to switch between branches if you have unmanaged files, meaning you have not committed them to your local branch. These files include: modified, added, removed files. Committing your changes to your local branch DO NOT affect the remote branches until you perform a ‘git push’. Do ‘git status’ to make sure all changes are push to your current remote branch before you switch to another branch.

$ ~/Documents/projects/project-android/ [develop] git status
On branch develop
Your branch is up to date with 'origin/develop'.

nothing to commit, working tree clean

Now it’s OK to switch branches:

$ git checkout <branch name>

File status lifecycle

Files within your git repository can be in 1 of 4 states:

  1. Untracked – New files within the repository that the previous snapshot does not know about. These would be files that were added to your local working copy but have yet to be added to GIT tracking

  2. Unmodified – Files within the repository that have do not have any modifications from the previous snapshot. In other words, GIT is tracking this file and you have yet to make any modifications to it

  3. Modified – Files within the repository that have had modifications compared to the previous snapshot.

  4. Staged – Files that have been committed to your local repository. This is similar to committing a file in Subversion however; the commit is local, whereas with SVN the commit is remote.

file_status_lifecycle


Determine the status of a file

To determine the status of a file, you will be using the “git status” command. See file status lifecycle for more information on status information.

git status <file>

Untracked files

New files added to the repository that did not exist in the previous snapshot

$ git status Makefile.mk
On branch develop
Your branch is up to date with 'origin/develop'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	Makefile.mk

nothing added to commit but untracked files present (use "git add" to track)

Unmodified files

Files that remain unchanged since the last snapshot

$ git status Makefile.mk
On branch develop
nothing to commit (working directory clean)

Modified files

Files that have changed since the last snapshot

git status Makefile.mk
On branch develop
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   Makefile.mk

no changes added to commit (use "git add" and/or "git commit -a")

Staging files

Files that have been locally marked for being committed to the Local/Remote repository

git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   Makefile.mk

Adding new/modified files to staging

Whenever you create/modify a file within the repository, the repository will not do anything with the file until you mark it for staging. This can be done using the git add command.

Applying this command will mark new and modified files ready for staging, which in essence means ready to commit to the local/remote repository.

$ git add <file>

NOTE: When you run the git add command, the file state at that exact moment will be marked for staging and will be ready for your next commit. If you alert the file at any point after that, the changes marked for staging will not change; they will reflect the state of the file at the time the “git add” command was performed. The additional changes will be marked as modified. You will have to re-run the “git add” command if you want the new changes to be marked for staging.


Removing a file from working copy

Whenever you want to remove a file from the working copy (e.g. remove a file from the repository on the next commit), you must use the git rm command. This will remove the file from being tracked and remove the physical file from disk.

$ git rm <file>
$ git rm –f <file>

Use the –f parameter to forcefully remove the file. This will be required when you have added/modified a file, committed it to staging, and then attempting to remove the file. If this is the case, you will need to force the removal.

To revert file has been remove by “git rm” we use

$ git checkout HEAD <file>

Renaming/moving a file within your working copy

To rename a file that already is being tracked within your local repository. There are 2 ways in which you can do this; the preferred method using GIT is the git mv command.

$ git mv <old file name> <new file name>

This will perform the following commands in 1 call instead of 3

$ <rename/move your file>
$ git rm <old file name>
$ git add <new file name>

Committing your local changes to your local repository

The git commit command will commit all files in staging to your local repository.

$ git commit –m”commit message to use”
$ git commit –m”commit message to use” [<file>...]

You must always provide a commit message. If a message is not provided, the default editor will be opened with the contents of the git status as your message (in most cases this is ‘vi’). You will then need to provide a message here.


Removing a modified file from staging, but keeping changes

In the case where you have added a file with modifications to staging (using “git add”), which marks this file to be committed on the next commit. However, let’s say you want to remove this file from staging (e.g. do not commit it on next commit) but you want to keep the modifications you made on it.

$ git reset <file>
$ git reset HEAD <file>

For example, let’s so I have added 2 files to staging and the status would look like this:

$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   Makefile.mk
	new file:   Minh.txt

Let’s say that I do not want to commit “Makefile.mk”, but I do not want to lose the changes I made to the file. In this case, I would use the reset command:

$ git reset Makefile.mk
Unstaged changes after reset:
M	Makefile.mk

Then proceeding to call “git status” would show that “Makefile.mk” has been removed from staging, but remains modified.

$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   Minh.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   Makefile.mk

Reverting changes made to a modified file

If you wanted to revert a given file to the snapshot state prior to your modifications, you we will need to use the git checkout command.

$ git checkout -- <file>

Use this command wisely; as once you have performed this command on a file, all changes will be forever lost!


Creating a local branch

Branches within GIT are just pointers to a specific snapshot within your set of commits. These areas SHA1 hashes. This makes creating and removing branches very efficient as it takes the same time as it takes to write 40 characters to a file. To create a new branch we will be using the git branch command

$ git branch <name of branch>

You can use git checkout –b <branch_name> – this command will create a new branch (if not exists) and switch to that new branch

$ git checkout -b test
Switched to a new branch 'test'

Renaming a local branch

Use the following command on the branch in which you are CURRENTLY working within (e.g. the branch that is currently checked out):

$ git branch –m <new branch name>

Removing a local branch

After you have finished with a bug/feature and it has been merged to the develop branch, you no longer need the bug/feature specific branch on your local system. These branches leave a very small footprint, so leaving them on your local disk does not impact you very much. If you want to remove a branch you will want to use the following command:

$ git branch –D <name of the branch>

Using –D will disregard any uncommitted changes. If you use –d then the branch will only be removed if it is fully merged (e.g. up-to-date).

Removing a remote branch

$ git push origin :<branchName>

Remove all untracked files

When switching from branch to branch, the untracked files will be left behind. These are not deleted as git does not know if you want to keep these files or not, so as a precaution they are left behind. If you wish to have git clear these for you, you can, using the ‘git clean’ command. First, I would recommend performing a dry run so you don’t delete anything you did not intend to:

$ git clean -n

This will show you all the files that will be deleted. By default, directories and subdirectories are not included. To include directories:

$ git clean -n -d

When you are happy with what the dry run states it will remove, you can perform the clean using the following:

$ git clean -f

To include directories:

$ git clean -d -f

To restore all those deleted files in a folder enter the following command

git ls-files -d | xargs git checkout --

Undoing merge

PLEASE PAY EXTRA CLOSE ATTENTION WHEN PERFORMING RESETS ON TRACKED BRANCHES! IF YOU RESET PASS OTHER DEVELOPERS CHANGES ON REMOTELY TRACKED BRANCHES, THEIR CHANGES WILL BE LOST AND WILL HAVE TO BE RE-MERGED! SEEK ADVICE IF YOU ARE UNSURE ABOUT YOUR RESET!

Each commit is a position within the repository in which we can revert to. When merging changes, all commits will be brought along with the changes. Each commit has SHA1 hash. You can view these hashes in the log. You likely do not need to view a large portion of the log, so you can specify the total number of entries as follows:

$ git log -n 2

This will display 2 log entries. Change the number ‘2’ to encompass the number of log entries you wish to view at a given time. This command will display output like the following:

commit 539b52ac06a4fa4c17904a09c2efb8ed4cb218c8 (HEAD -> develop, origin/develop)
Merge: 774ccab5993 b93ce3aa143
Author: minhpd <minhpd@vng.com.vn>
Date:   Mon Feb 17 18:28:18 2020 +0700

    Merge branch 'feature-branch' into 'develop'

    Remove unuse package

    See merge request minhpd/project-android!2708

commit b93ce3aa143c7f2f55528b4b841991f86ef60a7a
Author: minhpd <minhpd@vng.com.vn>
Date:   Fri Feb 14 10:59:23 2020 +0700

    Refactor Utils, move all functions into core

In order to revert a stream to a given commit, you need to perform the following command:

$ git reset –-hard [SHA1]

Here the [SHA1] is the first few characters in the command hash. For example, if you wanted to revert my current working branch to the “Refactor Utils, move all functions into core”, you would perform the following command:

$ git reset –-hard b93ce3a

NOTE: You must be VERY careful if you are reverting changes on tracked branches. If you reset past other developers commits, these will also be removed. In these cases, you will need to remerge in their changes. Please seek advice if you have to reset changes out of the remotely tracked branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment