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 1
and option namedepth
indicate 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 --mirror
to finish process.
Diff Operation
- You can use command
git diff --staged
to check the differences between the staged file and file in the HEAD and append parameter--word-diff
can 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--force
can 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 --tags
to see all tags andgit show-ref --heads
to see all branches.
-
Inside command
git pull
are actually two other commandsgit fetch
andgit merge
. -
If you are not for sure when running some delete or any other dangerous commands, please use the
--dry-run
option 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-parse
to 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 --tags
to generate version number and the format is<latest-tag>-<commit-amount-to-the-latest-tag>-<latest-commit-SHA-1>
.
-
Command
git reflog
record every action that affect the HEAD pointer and actually, it is an alias forgit log --walk-reflogs --abbrev-commit --pretty=oneline
and it only reflect those changes which happened in local machine. Commandgit reflog expire --expire=now --all
can clear all existed reflog and generally, we just use commandgit reflog expire --expire-unreachable=now --all
so 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 fsck
to verify the integrity of the repository after you hit some hard disk problem which may hurt the current local git database (.git folder). -
Appending
--web
option 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
--merges
or--min-parents=2
flag used bygit log
will only show merge commits and if you do want every merge processes have a separated commit, you should useno-ff
option when you merge branches.
- With
--no-ff
option:
- Default:
-
Choose appropriate strategy to merge the branch like
git merge --strategy=recursive
and you can also use the--strategy
option to transfer some options. -
Using
git checkout -b <branch-name>
to create a new branch base on current branch and appendbased-on-ref
option 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
.gitignore
file and meanwhile, you should avoid use commandgit add --force <file-path>
to add ignored file. Another way is usinggit update-index --assume-unchanged
to ignore some specific files so that git will no longer check those files and you can usegit ls-files -v
to 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-unchanged
to those files. -
git reset --mixed
only undoes files added by commandgit add
like commandgit checkout --force
but commandgit reset --hard
undoes all file modifications including files added bygit add
The default reset algorithm for this command is mixed. In short, rememberhard
option resets the index and the working directory, andmixed
option resets the index but not the working directory. -
The command
git clean -X
will only remove ignored files from the working directory but option-x
will remove not-only those ignored files but all the untracked files like using commandgit clean --force
- Recommand using command
git clean -i
intuitivilty to remove files.
-
If you want to keep the top stack stash, you can use
git stash apply
instead ofgit stash pop
. -
The command
git bisect
is 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|bad
to label the commit. - Git will find the first bad commit.
- Use command
git bisect reset
to stop.
-
Command
git commit --amend
can rewrite the latest commit’s message. Inside this process, there are two operation. -
Often
git clean -xdf
is run aftergit reset --hard
to make sure the repository is clean. -
You can use
git log --format=email
to 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 --rebase
to replacegit pull
and 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
--edit
option to add some commit message or use--signoff
to clearly indicate who do that. If you hit merge conflict, please usegit cherry-pick --continue
orgit cherry-pick --abort
to 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--signoff
option, but this is quite different thanrebase
which 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-message
and 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.
--global
option will use the file in your$HOME
directory.--system
option will use the file alongside with the folder in which Git was installed.--local
option will use the file alongside with current repository. The default option is this.--file
option 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.prune
to 1 will trigger the commandgit remote prune
on everygit fetch
orgit pull
operation. -
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
$HOME
directory and use commandgit config --global core.excludesfile ~/.gitignore
to 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 1
to 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-name
to initialize the repository and in that case, this repo will only allow changes pushed from other repository. -
Command
git add --patch
can 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 init
to 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 update
to update the stored submodule revision to the latest revision in the local. It also provide you two useful options:--recursive
and--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--depth
option.
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/modules
too. 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
,$sha1
and$toplevel
.