25 Git Advanced Skills (translation) _linux

Source: Internet
Author: User
Tags diff garbage collection gpg rollback sha1 sha1 hash using git

I've been using git for almost 18 months and feel like I'm already very knowledgeable about it. Then Scott Chacon, from GitHub, came over to train LVs (LVs is a gambling software vendor and developer, a contract that began in 2013), and I learned a lot on the first day.

As someone who feels good about git, I think sharing some valuable information from the community might help someone solve a problem without doing too much research.

Basic Skills

1. The first step after installation

After you install Git, the first thing you should do is set your name and email address, because you need to use this information for each submission:

$ git config--global user.name "Some One"
$ git config--global user.email "someone@gmail.com"

2. Git is based on pointers

Everything saved in Git is a file. When you create a submission, a file containing your submission and related data (name, email address, date/time, previous submission, etc.) is created and linked to a tree file. This tree file contains a list of objects or other trees. The object mentioned here (or binary large object) is the actual content associated with this submission (it is also a file, in addition, although the file name is not included in the object, but stored in the tree). All of these files use the SHA-1 hash value of the object as the file name.

In this way, a branch and a label are simple files (basically) containing a SHA-1 hash value that points to the commit. Using these indexes provides excellent flexibility and speed, such as creating a new branch simply by using the branch name and the submitted SHA-1 index to create a file. Of course, you don't have to do this on your own, as long as you use the Git command-line tool (or GUI), but it's actually that simple.

You may have heard of the index called head. This is just a simple file that contains the SHA-1 index value of the submission you are currently pointing to. If you're working on a merge conflict and then you see head, it's not a special branch or branch that's a required special location, just indicate where you are now.

All branch pointers are saved in. Git/refs/heads, head is in Git/head, and tags are kept in. git/refs/tags-You can go in and see for yourself.

3. Two Dads (parent node)-You're right!

When you view a consolidated submission in history, you will see two parent nodes (different from regular submissions on the working copy). The first parent node is the branch you are in, and the second is the branch you merged with.

4. Merge conflict

At the moment I believe you have encountered a merger conflict and solved it. Usually edit the file, remove the <<<<,====,>>>> logo, and keep the code that needs to be left behind. Sometimes it would be nice to see the code before these two changes, for example, before the two branches that are now conflicting. Here's a way:

$ git diff--merge
diff--cc dummy.rb 
index 5175dde,0c65895 ... 4a00477 
---a/dummy.rb
+++
b/dummy.rb @@@ -1,5-1,5 +1,5 @@@ -1,5-1,5
 myfoo
 def say
-  puts " Bonjour "
 -puts" Hello World "
+ + puts" Annyong haseyo "End
 

If it is a binary file, the difference is not so simple ... Usually all you have to do is test the two versions of this binary file to decide which (or manually copy the conflict section in the binary editor). Obtain a copy of a file from a specific branch (for example, you are merging two branches of Master and feature123):

$ git checkout master Flash/foo.fla # or ...
$ git checkout feature132 flash/foo.fla
$ # then ...
$ git Add flash/foo.fla

Another way is to use Git to output files-you can output to another file name, and then when you decide which to use, then copy the selected correct file to the normal file name:

$ git show master:flash/foo.fla > Master-foo.fla
$ git show feature132:flash/foo.fla > Feature132-foo.fla
$ # Check out Master-foo.fla and Feature132-foo.fla
$ # If we decide that the file from feature132 is correct
$ rm flash/foo.fla
$ mv FEATURE132-FOO.FLA flash/foo.fla
$ rm master-foo.fla
$ git add flash/foo.fla

Update: Thanks to Carl for reminding you in the comments in the original blog post, you can actually check out a specific version of the file with "Git checkout-ours flash/foo.fla" and "Git checkout-theirs flash/foo.fla". Instead of remembering the branch names that you are merging. Personally, I like to be more precise, but it's also a way ...

Remember to add the file to the commit (as I did above) after resolving the conflict.

servers, branches, and labels

5. Remote server

One of the most powerful features of Git is that you can have more than one remote server (you're actually working in a local warehouse all the time). You don't have to have permission to write these servers, you can have multiple servers that can be read (to merge their work) and write to another repository. Adding a new remote server is simple:

$ git remote add John Git@github.com:johnsomeone/someproject.git

If you want to view the remote server information you can do this:

# Display URL for each remote server
$ git remote-v 
 
# provide more details
$ git remote show name 

You can always see the difference between a local branch and a remote branch:

$ git diff master. John/master

You can also view changes to the head that are not on the remote branch:

$ git log remote/branch ...
# Note:. A specific reference with no end later

6. Label

There are two types of tags in git-lightweight tags and annotated labels. Remember that trick 2 says that Git is based on pointers, and the difference between the two is simple. Lightweight tags are just a simple pointer to a submit with a name. You can always point it to another submission. A tagged tag is a name pointer to a label object with its own information and history. Because of its own information, it can be signed with GPG as needed.

Creating both types of labels is simple (only one command line switch differs)

$ git tag to-be-tested
$ git tag-a v1.1.0 # will prompt for information on the label

7. Establishing a Branch

Building a branch in Git is simple (and as fast as lightning, because it only needs to create a file that is less than 100 bytes). Create a new branch in a normal way and switch to the past:

$ git branch feature132
$ git checkout feature132

Of course, if you're sure you're switching to a new branch directly, you can do it with a single command:

$ git checkout-b feature132

If you want to rename a local branch It is also very simple (you can show what happened in a longer way):

$ git checkout-b twitter-experiment feature132
$ git branch-d feature132

Update: You can also (as Brian Palmer in the comments in the original blog post) implement only the "Git branch"-m switch in a command (as Mike puts it, if you specify only one branch parameter, you rename the current branch):

$ git branch-m twitter-experiment
$ git branch-m feature132 twitter-experiment

8. Merging branches

Maybe at some point in the future, you want to merge the changes. There are two ways of doing this:

$ git checkout master
$ git merge feature83 # or ...
$ git rebase feature83

The difference between merge and rebase is that the merge will try to process the changes and create a new mixture of both submissions. Rebase will try to add all the changes you have made to the head of the branch after the last separation from one branch. However, do not rebase after you have pushed the branch to a remote server-this can cause conflicts/problems.

If you're not sure which branches have a single job-so you don't know which branches need merging and which can be removed, git branch has two switches to help you:

# Show branches that have all been merged into the current branch
$ git Branch--merged
 
# Show branches that are not merged into the current branch
$ git branch--no-merged

9. Distal Branch

If you have a local branch that you want to push to a remote server, you can push it up with one line of command:

$ GIT push Origin twitter-experiment:refs/heads/twitter-experiment
# origin is the name of our server, and Twitter-experiment is the branch name

Update: Thank Erlend for commenting on the original blog post-this actually andgit push origin twitter-experiment效果一样,不过使用完整的语法,你可以在两者之间使用不同的分支名(这样本地分支可以是add-ssl-support而远端是issue-1723)。

If you want to delete a branch on the remote server (note the colon in front of the branch name):

$ git push origin:twitter-experiment

If you want to see the status of all the remote branches you can do this:

$ git Remote show origin

This command may list some of the servers that have previously been but are no longer present. If this is the case, you can remove it from your local branch with the following command:

$ git remote prune

Finally, if you want to track a remote branch locally, the normal way is:

$ git Branch--track myfeature origin/myfeature
$ git checkout myfeature

However, the new version of Git automatically sets the trace when the branch is checked out using the-B tag:

$ git checkout-b myfeature origin/myfeature

Save content in storage points, indexes and file systems

10. Storage

In git you can put your current working state into a storage stack and then you can take it out again. The simplest scenario is the following:

$ git Stash
# do something else ...
$ git stash pop

Many people suggest usinggit stash apply来代替pop,不过如果这样做的话最后会遗留一个很长的储藏列表。而“pop”会在全部加载后自动从堆栈中移除。如果使用过git stash apply,你也可以使用下面的命令从堆栈上移除最后一项:

$ git stash Drop

Git automatically creates comments based on the current submission information. If you prefer to have custom information (since it may not have any connection to the previous submission):

$ git stash save "my stash message"

If you want to remove a specific storage point from the list (not necessarily the last one), you can list them and then take them out in the following way:

$ git stash list
 stash@{0}: On master:changed to German
 stash@{1}: On Master:language are now Italian
$ git s Tash Apply Stash@{1}

11. Interactive Add

In the Subversion world you can only modify the file and submit all changes. And in Git you have a much more powerful way to submit parts of a file or even a partial patch. Some of the changes in the submission part of the file or file you need to enter interactive mode:

$ git add-i
   staged  unstaged path
 
 
Commands * * * 1:status  2:update 3:revert 4:add untracked
 5:patch  6:diff  7:quit  8:help
What now> 

This will give you access to a menu based interactive hint. You can use the numbers in the command or the highlighted letters (if you open the highlight in the terminal) to enter the appropriate mode. Then just type in the number of files you want to manipulate (you can use this format, 1 or 1-4 or 2,4,7).

If you want to go into patch mode (in interactive mode press ' P ' or ' 5 '), you can also go directly to:

$ git add-p 
diff--git a/dummy.rb b/dummy.rb 
index 4a00477. F856FB0 100644 
---a/dummy.rb
+++
b/dummy.rb @@ -1,5 +1,5 @@ -1,5
 myfoo
 def say
-puts "Annyong Haseyo "
+ puts" Guten Tag "end end
 Stage this
hunk [Y,n,q,a,d,/,e,?]? 

You can see that there are some options to choose from to add this change to the file, all the changes to the file, and so on. Use '? ' Commands can explain these options in detail.

12. Save/Retrieve changes from file system

Some projects, such as the GIT project itself, save additional files directly in the Git file system without adding them to version control.

Let's start by storing a random file in git:

$ echo "Foo" | git hash-object-w--stdin
51FC03A9BB365FAE74FD2BF66517B30BF48020CB 

The target file is saved to the database, but if you don't set a pointer to it, it will be garbage collected. The easiest way to do this is to set a label:

$ git Tag myfile 51FC03A9BB365FAE74FD2BF66517B30BF48020CB

Note that we use the tag myfile here. This can be done when we need to use this file:

$ git cat-file blob myfile

This is useful for some tool files that developers may use (passwords, GPG keys, etc.) but do not want to check out the hard drive every time (especially in actual work).

What are the logs and what are the changes?

13. View Log

Using Git for a long time does not use ' git log ' to view recent submissions. However, there are some techniques for better application. For example, you can use the following command to view specific changes that are submitted each time:

$ git log-p

Or you can just see what file changes are:

$ git log--stat

There's a nice alias. You can try it, display a short submit name and a nice branch diagram and display the submission in one line (a bit like GITK, but at the command line):

$ git config--global alias.lol "log--pretty=oneline--abbrev-commit--graph--decorate"
$ git lol
* 4d2409a (MA ster) Oops, meant that to being in Korean
* 169b845 Hello World

14. Search Log

If you want to find a specific submitter you can do this:

$ git log--author=andy

Update: Thanks to Johannes's comments, I've removed some of the confusing places here before.

Or do you want to find some relevant fields in the submission information:

$ git log--grep= "something in"

There is also a more powerful command called Pickaxe to find a submission that contains a specific content that was deleted or added (for example, the content was first seen or deleted). This will tell you when to add a line (but not after a character in this line is changed):

$ git log-s "todo:check for admin status"

If you change a particular file, such aslib/foo.rb

$ git log lib/foo.rb

For example, you have afeature/132分支和feature/145分支,然后你想看看这两个分支上不在master分支里的提交(注意符号是不在的意思):

$ git log feature/132 feature/145 ^master

You can also use the Activesupport format date to narrow down to a date range:

$ git log--since=2.months.ago--until=1.day.ago

By default, the query is combined with or, but you can easily change to and (if you have more than one query criterion)

$ git log--since=2.months.ago--until=1.day.ago--author=andy-s "Something"--all-match

15. View/Modify Version

There are many ways to refer to a version to see which one you remember:

$ git show 12a86bc38 # according to version $ git show
v1.0.1 # according to label
$ git show feature132 # according to branch name
$ git show 12a86bc38^ # a mention Cross parent node
$ git show 12a86bc38~2 # once submitted grandparents node
$ git show Feature132@{yesterday} # Time related
$ git show Feature132@{2.hou Rs.ago} # Time related

Notice the difference from the previous part, which means the parent node of the submission -the starting position means not in this branch.

16. Select Range

The simplest way:

$ git log origin/master ... New
# [old]. [New]-All the submissions you haven't pushed yet

You can also omit [new] and use the current head.

Time backtracking and regret medicine

17. Reset Changes

If you have not yet submitted, you can use the following command to easily cancel the changes:

$ git reset head lib/foo.rb

The alias of ' unstage ' is usually used because the above looks somewhat counterintuitive.

$ git config--global alias.unstage "reset Head"
$ git unstage lib/foo.rb

If you have already submitted the file, you can do two things-if the last submission you can also correct:

$ git commit--amend

This cancels the last commit, marks the status of all changes before submitting the work branch back to submission, and the submission is ready to be modified or submitted directly.

If you have submitted multiple times and want to roll back all, you can reset the branch to the appropriate location.

$ git checkout feature132
$ git reset--hard head~2

If you actually want to point the branch to a completely different SHA1 (perhaps you want to replace the head of a branch with another branch, or a subsequent commit) you can use the following longer way:

$ git checkout FOO
$ git reset--hard SHA

There is actually a quick way (you don't have to switch your work branch to Foo to go to sha):

$ git update-ref refs/heads/foo SHA

18. Submitted to the wrong branch

Well, if you've already submitted to master, you should create a topic branch called experimental more appropriate. To move these changes, you can create branches in the current location, rollback head, and then check out the new branch:

$ git Branch Experimental # Create a pointer to the location of the current master
$ git reset--hard master~3 # Move Master Branch pointer to 3 versions before
$ git checkout Experimental

If your changes are more complex on branches of branch branches. So what you need to do is switch the branch base to another place:

$ git Branch newtopic startpoint
$ git rebase oldtopic--onto newtopic

19. Interactive Switching Basics

This is a great feature that I've seen before but I don't really understand, and now I think it's very simple. If you have submitted 3 times but you want to change the order or edit (or merge):

$ git rebase-i master~3

Then this will start your editor and take some instructions. All you have to do is modify these instructions to select/Insert/edit (or delete) Submit and save/exit. And then, after the editing, you can usegit rebase --continue命令来让每一条指令生效。

If you have a change, you will be able to switch to the state you submitted to, and then you'll need to use the command git commit--amend to edit it.

Note: Never commit when rebase-you can only add and then use Parameters--continue,--skip or--abort.

20. Cleaning up

If you submit some content to your branch (perhaps you've imported some old warehouses from SVN), then you want to delete a file from the history:

$ git filter-branch--tree-filter ' rm-f *.class ' head

If you have already pushed to Origin, but then submitted some garbage changes, you can do so in the local system before the push:

$ git filter-branch--tree-filter ' rm-f *.class ' origin/master. Head

Other Tips

21. The previous reference you have viewed

If you know you've seen a SHA-1 before, but then you've done some reset/rollback, you can use the Reflog command to list the SHA-1 records you've recently viewed:

$ git reflog
$ git log-g # and above, but using ' log ' format output

22. Branch naming

A cute little trick-don't forget the branch name is not limited to a-Z and 0-9. The name can be used/and. It will be very handy to create a pseudo namespace or version, for example:

$ # Build Version 132 change history
$ git shortlog release/132 ^release/131
$ # Paste v1.0.1 tag
$ git tag v1.0.1 release/132

23. Find out who the murderer is.

It is often useful to find out who changed a line of code in a file. The simplest commands to implement this feature are:

$ git blame FILE

Sometimes these changes come from other files (if you merge two files, or if you move a function), you can use the following command:

$ # show which file the content is from
$ git blame-c file

Sometimes it would be nice to click on each change and go back to a long time ago to track the changes. There is a good built-in GUI command to do this:

$ git gui blame FILE

24. Data Maintenance

Often git does not need regular maintenance, it takes care of itself very well. However, you can view data statistics by using the following command:

$ git count-objects-v

If you occupy a lot of space, you can choose to do garbage collection in your local warehouse. This will not affect the push or others, but will make some commands run faster and reduce space usage:

$ git GC

Often running integrity checks also make sense:

$ git fsck--full

You can also add at the end--auto参数(如果你在服务器上通过crontab经常/每天都运行这个命令的话),然后它只会在必要的时候才执行fsck动作。

It is normal to see "dangling" or "unreachable" at the time of the check, usually the result of a fallback head or switch base. and see "Missing" or "SHA1 mismatch" is wrong ... Find a professional to help you!

25. Restoration of Lost branches

If you delete the experimental branch using the-D argument, you can re-establish it with the following command:

$ git Branch experimental Sha1_of_hash

If you have recently visited, you can usually use Git reflog to find the SHA1 hash value.

Another way is to usegit fsck —lost-found。其中一个dangling的提交就是丢失的HEAD(它只是已删除分支的HEAD,而HEAD被引用为当前的HEAD所以它并不处于dangling状态)

Get!

Wow, this is the longest blog I've ever written, and I want someone to feel useful. If you feel that way, or if you have any questions please leave a message in the comments and let me know ...

via:https://www.andyjeffries.co.uk/25-tips-for-intermediate-git-users/

Author: Andy Jeffries Translator: zpl1025 proofreading: Wxy

This article by LCTT original translation, Linux China honor launch

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.