Remote Operation
-
The command
git remote prune <git-repo-path>deletes any remote references to branches that have been deleted from the remote repository by other users. See more about this . -
Please be very careful when you run command
git push --forced, it’s very dangerous because it will rewrite all you related histories in the remote side. -
When you want to clone a very large repository in a very short time, you can use command like
git clone --depth 1and option namedepthindicate specific versions/levels and in this case it will only clone the latest version. -
Transfer repository through different manage physical repository:
- Use command
git clone --mirror git@bitbucket.org:<user-name>/<repo-name> - Use command
git remote set-url --push git@github.com:<user-name>/<repo-name> - Use command
git push --mirrorto finish process.
Diff Operation
- You can use command
git diff --stagedto check the differences between the staged file and file in the HEAD and append parameter--word-diffcan show modifications per word.
- Remember to setup the merge tool so that no need to install the software like source tree. For me, I use tool name icdiff.
Tag Operation
- You can use
git tag <tag-name>to make a label for specific commit. If you want to update the software, just release a new one. A tag is another ref for a single commit. Tags differ from branches in that they’re usually permanent, so don’t change the label later and also use option--forcecan make an existing tag direct to a new commit.
- By the way, if you want to push tags, you should use
git push -tags. If you have to change tags that already been pushed to the remote, you can usegit push --tags --force, but creating a new tag and pushing that new one is recommended since it will have no bad effect on other people.
Useful Skills and Knowledges
- You can use command
git show-ref --tagsto see all tags andgit show-ref --headsto see all branches.
-
Inside command
git pullare actually two other commandsgit fetchandgit merge. -
If you are not for sure when running some delete or any other dangerous commands, please use the
--dry-runoption if it’s existed.
- You can use the
--option between ref and file paths to avoid “strange” name.
- You can also use command tool
rev-parseto see what a given ref expands to, but usually a four-character string is unique enough to identify the specific commit.
- We can use git shortlog to see who contributes most.
- You can enable git rerere to automatically resolve these same conflicts and use git rerere forget *** to ignore some previous wrong conflict fix.
- You can use command
git describe --tagsto generate version number and the format is<latest-tag>-<commit-amount-to-the-latest-tag>-<latest-commit-SHA-1>.
-
Command
git reflogrecord every action that affect the HEAD pointer and actually, it is an alias forgit log --walk-reflogs --abbrev-commit --pretty=onelineand it only reflect those changes which happened in local machine. Commandgit reflog expire --expire=now --allcan clear all existed reflog and generally, we just use commandgit reflog expire --expire-unreachable=now --allso that the operation will only apply to those unreachable ref logs. -
You can use
git cherry --verbose <branch-ref>to see which commits have not yet been merged or pushed to the remote. It will compare the current branch with the branch you dictate in the parameter, the default value which can be ignored is the remote branch. -
Always remember to differentiate author with committer and use
git blame <file-path>to see editor’s information about every line of the file even you rename the file itself.
-
You should use command
git fsckto verify the integrity of the repository after you hit some hard disk problem which may hurt the current local git database (.git folder). -
Appending
--weboption to thegit help <command>can show help file in HTML version in the browser.
Branch Operation
-
An advice to naming the new branch: using multiple words separated by hyphens like
fix-feature-a. -
A
--mergesor--min-parents=2flag used bygit logwill only show merge commits and if you do want every merge processes have a separated commit, you should useno-ffoption when you merge branches.
- With
--no-ffoption:
- Default:
-
Choose appropriate strategy to merge the branch like
git merge --strategy=recursiveand you can also use the--strategyoption to transfer some options. -
Using
git checkout -b <branch-name>to create a new branch base on current branch and appendbased-on-refoption can give you more precise control.
Local Operation
-
Mostly, git will recognize file’s rename and movement and if it doesn’t, you should use
git mv <file-path>to do that. Remember, git doesn’t handle moving files between different repositories and it only take care of its own repository. -
If you really need to neglect some specific files, please put those rules in the
.gitignorefile and meanwhile, you should avoid use commandgit add --force <file-path>to add ignored file. Another way is usinggit update-index --assume-unchangedto ignore some specific files so that git will no longer check those files and you can usegit ls-files -vto see all the files including those ignored files. By the way, if you want to re-check those files, you can rungit update -index --no-assume-unchangedto those files. -
git reset --mixedonly undoes files added by commandgit addlike commandgit checkout --forcebut commandgit reset --hardundoes all file modifications including files added bygit addThe default reset algorithm for this command is mixed. In short, rememberhardoption resets the index and the working directory, andmixedoption resets the index but not the working directory. -
The command
git clean -Xwill only remove ignored files from the working directory but option-xwill remove not-only those ignored files but all the untracked files like using commandgit clean --force
- Recommand using command
git clean -iintuitivilty to remove files.
-
If you want to keep the top stack stash, you can use
git stash applyinstead ofgit stash pop. -
The command
git bisectis very useful to find which commit may have a regression bug and you can provide a test script which has defined output so that the git will automatically run this script on each commits so that you can identify which commit has broken.
- Use command
git bisect start. - Use command
git bisect good|badto label the commit. - Git will find the first bad commit.
- Use command
git bisect resetto stop.
-
Command
git commit --amendcan rewrite the latest commit’s message. Inside this process, there are two operation. -
Often
git clean -xdfis run aftergit reset --hardto make sure the repository is clean. -
You can use
git log --format=emailto decide whether the commit content is good or not and you can also to write your own format style for other purposes which means when you are writing the commit message, you should use the way to write the email. For example, the commit should have “subject” and “content”. -
You can use
git pull --rebaseto replacegit pulland it will make the history look more flatten by avoiding a single new merge commit. -
You can use
git filter-branch <command>to do some entire history for repository. For example, you can rewrite author info totally.
Rewrite History
-
When you use function name cherry-pick, remember to use
--editoption to add some commit message or use--signoffto clearly indicate who do that. If you hit merge conflict, please usegit cherry-pick --continueorgit cherry-pick --abortto submit or ignore this change and the “continue, abort” pattern are also appropriate torebase. -
You can use
git revert <commit>to undo one specific commit and also remember to use--signoffoption, but this is quite different thanrebasewhich will change the history instead of appending a new one.
- At first, git will run command
git reset --soft HEAD^.
- Before:
- After:
- Restore:
Then, it will run command
git commit --reedit-messageand open the editor for you to change the message.
Notice: This will rewrite the history and need --force option to push changes to the remote.
- By the way,
git reset --soft ***will rests neither the staging area nor the working tree but just changes the HEAD pointer to point to the previous commit.
Personalize Git
- Remember, when using command
git log <location> <section>.<key> <value>to write value, you can point out which one you want to change.
--globaloption will use the file in your$HOMEdirectory.--systemoption will use the file alongside with the folder in which Git was installed.--localoption will use the file alongside with current repository. The default option is this.--fileoption let you to provide the file path.
Priority list: --file > --local > --global > --system.
By the way, Git sets values in a branch section in the --local position so that it will know how to pull or merge the code.
-
By default, when you execute command
git push, Git will push all related branchs’ changes to the remote. It will accidentally push changes made on other branches. So, you can set the default push strategy tosimple. -
{#git-remote-prune#} By setting
fetch.pruneto 1 will trigger the commandgit remote pruneon everygit fetchorgit pulloperation. -
Git allows you to set a global ignore file so that you can put your personal ignore rules in it. That is very useful if you are working with other teammates who may have different opinion on ignore rules. Usually, we put our own global ignore file in the
$HOMEdirectory and use commandgit config --global core.excludesfile ~/.gitignoreto identify it. -
For people who are using Mac OS X can store their password in the keychain which is natuely supported by the Git. The command is
git config --global credential.helper oskeychain. -
Use
git config --global help.autocorrect 1to let Git fix your wrong spell commands.
Advice
-
The main rule to avoid data loss therefore is commit early and commit often. Always try to use make/rewrite commits instead of stash, because cleared stashes can’t be easily recovered.
-
Never write history on branches which other people may use and remember to pull the source first so that you aren’t rewriting commits on the remote branch that you don’t have locally.
-
If you just want to create a public repository and put it on the internet, you could use
git init --bare repo-nameto initialize the repository and in that case, this repo will only allow changes pushed from other repository. -
Command
git add --patchcan allow you stage changes one by one.
Submodule
- Use command
git submodule add <repository_address> <local_path>to add submodule. Git’s submodules store the the reference to a specific SHA-1 reference in another remote Git repository and store these in subdirectories of the current repository.
By the way, it also provide --depth option like git clone.
- Use command
git submodule initto initialize all submodules which will copies all the submodule names and URLs from the .gitmodules file to the local repository Git configuration file so that when you rungit pull, Git will knows to pull the latest changes for submodules.
- Use command
git submodule updateto update the stored submodule revision to the latest revision in the local. It also provide you two useful options:--recursiveand--init. The first option is useful when there are nested submodules inside submodules. The second option can help you to avoid rungit submodule init. This command also provides--depthoption.
Please testing the changes made to the submodule remain compatible with the main project.
-
When you try to entirely clean up submodules, please remember to delete folder name
.git/modulestoo. Because Git will initially cloned submodules to this folder and then copy that to the path that you indicated. -
git submodule foreach <command>is very useful for you to run command on all submodules and with option--recursive, it can touch all submodules. The command can access to below variables:$name,$path,$sha1and$toplevel.