Share 45 classic Git operation scenarios, tyranny will not conform to the code

a66b3b17a52ba900ca30b44ad93f88f4.jpeg

Git should not be unfamiliar to everyone, proficient use of git has become a basic skill for programmers, although there are awesome client tools such as Sourcetree in the work, which makes merging codes very convenient. But for job interviews and some scenes that need to show personal strength, we still need to master enough git commands.

Below we have sorted out 45 classic operation scenarios for daily use of git to combine codes, which basically cover the needs of work.

What did I just submit?

If you  git commit -a submit a change (changes) with , and you are not sure what content was submitted this time. You can use the following command to display HEADthe latest commit (commit):

(main)$ git show

or

$ git log -n1 -p

My commit message is wrong

If your commit message is written wrong and this commit has not been pushed yet, you can modify the commit message by the following method:

$ git commit --amend --only

This will open your default editor, where you can edit the message. Alternatively, you can do it all at once with a single command:

$ git commit --amend --only -m 'xxxxxxx'

If you have already pushed this commit, you can modify this commit and force push, but this is not recommended.

The user name and email address in my commit (commit) are wrong

If this is just a single commit, modify it:

$ git commit --amend --author "New Authorname <[email protected]>"

If you need to modify all history, refer to the 'git filter-branch' guide page.

I want to remove a file from a commit

Remove a file from a commit by:

$ git checkout HEAD^ myfile
$ git add -A
$ git commit --amend

This will be very useful when you have an open patch (open patch), you submit an unnecessary file to it, and you need to force push (force push) to update the remote patch.

I want to delete my last commit (commit)

If you need to delete pushed commits, you can use the following method. However, this will irreversibly change your history and mess up the histories of those who have already pulled from the repository. In short, if you're not sure, don't do it.

$ git reset HEAD^ --hard
$ git push -f [remote] [branch]

If you haven't pushed to the remote yet, just reset Git to where it was before your last commit (while saving the staged changes):

(my-branch*)$ git reset --soft HEAD@{1}

This only works if you haven't pushed before. If you've already pushed, the only safe thing to do is  git revert SHAofBadCommitto create a new commit that undoes all the changes from the previous commit; or, if you push This branch of is rebase-safe (for example: other developers will not pull from this branch), just use it  git push -f.

Delete any commit

Same warning: don't do this unless you absolutely have to.

$ git rebase --onto SHA1_OF_BAD_COMMIT^ SHA1_OF_BAD_COMMIT
$ git push -f [remote] [branch]

Or do an interactive rebase and delete the lines corresponding to the commits you want to delete.

I tried to push an amended commit (amended commit) to the remote, but got an error:

To https://github.com/yourusername/repo.git
! [rejected]        mybranch -> mybranch (non-fast-forward)
error: failed to push some refs to 'https://github.com/tanay1337/webmaker.org.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Note that rebasing (see below) and amending will replace the old commit with a new one , so if you have pushed a pre-amended commit to the remote repository before, you must now Force push ( -f). Note –  always  make sure you specify a branch!

(my-branch)$ git push origin mybranch -f

In general,  avoid pushing . It is better to create and push a new commit than to push a revised commit. The latter would create conflicts in the source history for developers working on that branch or a subbranch of that branch.

I accidentally did a hard reset and I want to get my content back

If you do it by accident  git reset --hard, you can usually get your commit back, because Git keeps a log of everything, and keeps it for a few days.

(main)$ git reflog

You'll see a list of your past commits, and a reset commit. Choose the SHA of the commit you want to go back to, and reset again:

(main)$ git reset --hard SHA1234

This is done.

Staging

I need to add the staging content to the last commit

(my-branch*)$ git commit --amend

I want to stage part of a new file, not the whole file

In general, if you want to stage a portion of a file, you do this:

$ git add --patch filename.x

-p Shorthand. This will open interactive mode and you will be able  s to separate commits with options; however, if the file is new, there will be no such option. When adding a new file, do this:

$ git add -N filename.x

Then, you need to use  e the option to manually select the lines to be added, and the execution  git diff --cached will show which lines are staged and which lines are only saved locally.

I want to add changes in one file to two commits

git add will add the entire file to a commit.  git add -p Allows interactive selection of the parts you want to commit.

I want to change the temporarily stored content to unscheduled, and temporarily store the unscheduled content

In most cases, you should make all content unstaged, and then select the content you want to commit. But assuming that's what you want to do, here you can create a temporary commit to save your staged content, then stage your unstaged content and stash. Then reset the last commit to change the originally staged content to unstaged, and finally stash pops back.

$ git commit -m "WIP"
$ git add .
$ git stash
$ git reset HEAD^
$ git stash pop --index 0

Note 1: This is used here poponly because we want to keep idempotent as much as possible. Note 2: If you don't add it --indexyou will mark the staged file as stored.

Unstaged content

I want to move unstaged content to a new branch

$ git checkout -b my-branch

I want to move unstaged content to another existing branch

$ git stash
$ git checkout my-branch
$ git stash pop

I want to discard local uncommitted changes (uncommitted changes)

If you just want to reset some commits between origin and your local, you can:

# one commit
(my-branch)$ git reset --hard HEAD^
# two commits
(my-branch)$ git reset --hard HEAD^^
# four commits
(my-branch)$ git reset --hard HEAD~4
# or
(main)$ git checkout -f

To reset a specific file, you can use the filename as an argument:

$ git reset filename

I want to discard some unstaged content

If you want to discard some of the contents of the working copy, but not all.

Check out what you don't need and keep what you need.

$ git checkout -p
# Answer y to all of the snippets you want to drop

Another way is to use  stash, Stash all the content you want to keep, reset the working copy, and reapply the preserved part.

$ git stash -p
# Select all of the snippets you want to save
$ git reset --hard
$ git stash pop

Alternatively, stash the parts you don't need, then stash drop.

$ git stash -p
# Select all of the snippets you don't want to save
$ git stash drop

Branches

I pulled content from or to the wrong branch

Here's another use  git reflog case, finding what HEAD was pointing to before this erroneous pull.

(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here

Reset the branch to your desired commit:

$ git reset --hard c5bc55a

Finish.

I want to throw away my local commits so my branch is consistent with the remote

Make sure you are not pushing your content to the remote.

git status will show how many commits you are ahead of origin:

(my-branch)$ git status
# On branch my-branch
# Your branch is ahead of 'origin/my-branch' by 2 commits.
#   (use "git push" to publish your local commits)
#

One way is:

(main)$ git reset --hard origin/my-branch

I needed to commit to a new branch, but made the wrong commit to main

Create a new branch under main without switching to the new branch, still under main:

(main)$ git branch my-branch

Reset the main branch to the previous commit:

(main)$ git reset --hard HEAD^

HEAD^ Yes  HEAD^1 shorthand, you can further reset by specifying what to set HEAD.

Or, if you don't want to use it  HEAD^, find the hash of the commit you want to reset to ( git log it can be done), and reset to that hash. Use to git push sync content to remote.

For example, the hash of the commit the main branch wants to reset to is a13b85e:

(main)$ git reset --hard a13b85e
HEAD is now at a13b85e

Check out (checkout) the newly created branch to continue working:

(main)$ git checkout my-branch

I want to keep the whole file from another ref-ish

Suppose you are working on a prototype project (the original text is working spike (see note)), there are hundreds of content, each of which works very well. Now, you commit to a branch and save your work:

(solution)$ git add -A && git commit -m "Adding all changes from this spike into one big commit."

When you want to put it into a branch (maybe feature, or  develop), you care about keeping the whole file intact, and you want to separate a large commit into smaller ones.

Suppose you have:

  • branch  solution, owning the prototype solution, leading  develop the branch.

  • Branch  develop, where you apply some content of the prototype scheme.

I guess you can fix this by pulling the content into your branch:

(develop)$ git checkout solution -- file1.txt

This will get the contents of this file from the branch  solution into the branch  develop :

# On branch develop
# Your branch is up-to-date with 'origin/develop'.
# Changes to be committed:
#  (use "git reset HEAD <file>..." to unstage)
#
#        modified:   file1.txt

Then, commit normally.

Note: Spike solutions are made to analyze or solve the problem. These solutions are used for estimation and discarded once everyone gets clear visualization of the problem.

I submitted several commits (commit) to the same branch, and these commits should be distributed in different branches

Suppose you have a mainbranch, execute git log, and you see that you made two commits:

(main)$ git log

commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <[email protected]>
Date:   Tue Jul 22 15:39:27 2014 -0400

    Bug #21 - Added CSRF protection

commit 5ea51731d150f7ddc4a365437931cd8be3bf3131
Author: Alex Lee <[email protected]>
Date:   Tue Jul 22 15:39:12 2014 -0400

    Bug #14 - Fixed spacing on title

commit a13b85e984171c6e2a1729bb061994525f626d14
Author: Aki Rose <[email protected]>
Date:   Tue Jul 21 01:12:48 2014 -0400

    First commit

Let's mark bugs with commit hash ( e3851e8 for #21,  5ea5173 for #14).

First, we mainreset the branch to the correct commit ( a13b85e):

(main)$ git reset --hard a13b85e
HEAD is now at a13b85e

Now, we create a new branch for bug #21:

(main)$ git checkout -b 21
(21)$

Next, we  cherry-pick  the commit for bug #21 into the current branch. This means we will apply (apply) this commit (commit), just this one commit (commit), directly above HEAD.

(21)$ git cherry-pick e3851e8

At this time, there may be conflicts here, see  the conflict section of the interactive rebasing chapter  to resolve conflicts.

Furthermore, we create a new branch for bug #14, also based on mainbranch

(21)$ git checkout main
(main)$ git checkout -b 14
(14)$

Finally, for bug #14 execute  cherry-pick:

(14)$ git cherry-pick 5ea5173

I want to delete the local branch where the upstream branch was deleted

Once you've merged a pull request on github, you can delete the merged branch in your fork. If you are not going to continue working in this branch, it will be cleaner to delete the local copy of this branch, so that you will not fall into the chaos of working branches and a bunch of old branches (playing with Git in IDEA ) .

$ git fetch -p

I accidentally deleted my branch

If you regularly push to the remote, it should be safe most of the time, but sometimes it is possible to delete branches that have not been pushed to the remote. Let's start by creating a branch and a new file:

(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
README.md foo.txt

Add files and do a commit

(my-branch)$ git add .
(my-branch)$ git commit -m 'foo.txt added'
(my-branch)$ foo.txt added
 1 files changed, 1 insertions(+)
 create mode 100644 foo.txt
(my-branch)$ git log

commit 4e3cd85a670ced7cc17a2b5d8d3d809ac88d5012
Author: siemiatj <[email protected]>
Date:   Wed Jul 30 00:34:10 2014 +0200

    foo.txt added

commit 69204cdf0acbab201619d95ad8295928e7f411d5
Author: Kate Hudson <[email protected]>
Date:   Tue Jul 29 13:14:46 2014 -0400

    Fixes #6: Force pushing after amending commits

Now we switch back to the main (main) branch and 'accidentally' delete my-branchthe branch

(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!

At this point you should remember reflog, an updated version of the log, which stores the history of all actions in the warehouse (repo).

(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from main to my-branch

As you can see, we have a commit hash from the deleted branch, let's see if we can restore the deleted branch.

(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
(my-branch-help)$ ls
README.md foo.txt

Look! We got the deleted files back. Git  reflog is also useful when rebasing goes wrong.

I want to delete a branch

Delete a remote branch:

(main)$ git push origin --delete my-branch

you can also:

(main)$ git push origin :my-branch

Delete a local branch:

(main)$ git branch -D my-branch

I want to checkout a branch from a remote branch that someone else is working on

First, fetch all branches from the remote:

(main)$ git fetch --all

Suppose you want to checkout from a remote davesbranch to a localdaves

(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'

( short for --track yes  git checkout -b [branch] [remotename]/[branch] )

In this way, you get a daveslocal copy of the branch, and any updates pushed (pushed) can be seen remotely.

Rebasing and Merging

I want to undo the rebase/merge

You could merge or rebase the wrong branch, or fail to complete a rebase/merge in progress. Git will save the original HEAD in a variable called ORIG_HEAD when performing dangerous operations, so it is very easy to restore the branch to the state before rebase/merge.

(my-branch)$ git reset --hard ORIG_HEAD

I have already rebase, but I don't want to force push

Unfortunately, if you want to reflect these changes (changes) to the remote branch, you have to force push (force push). It is because you fast-forwarded the submission and changed the Git history, and the remote branch will not accept the changes (changes) unless it is forced to push (force push). This is one of the main reasons why many people use the merge workflow instead of the rebasing workflow, a force push by the developer can get large teams into trouble. Note when using it, a safe way to use rebase is not to reflect your changes (changes) to the remote branch, but to do the following:

(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch

I need to combine several commits

Assume your working branch will do  main the pull-request for it. Normally you don't care about commit timestamps, you just want to combine  all  commits into a single one, then reset and recommit. Make sure the main branch is up to date and your changes are committed, then:

(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"

If you want more control, and want to preserve timestamps, you need to do an interactive rebase (interactive rebase):

(my-branch)$ git rebase -i main

If there is no other branch against, you will have to HEAD rebase against your own. For example: you want to combine the last two commits (commit), you will rebase relative to HEAD~2 , combine the last three commits (commit), relative to HEAD~3, and so on.

(main)$ git rebase -i HEAD~2

After you execute the interactive rebase command, you will see something like this in your editor:

pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
pick b729ad5 fixup
pick e3851e8 another fix

# Rebase 8074d12..b729ad5 onto 8074d12
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

All  # lines starting with are comments and will not affect rebase.

Then, you can substitute any of the commands listed above  pick, and you can also delete a commit by deleting the corresponding line.

For example, if you want to  keep the oldest (first) commit alone, and combine all the rest into the second , you should edit the The words are  f:

pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
f b729ad5 fixup
f e3851e8 another fix

If you want to combine these commits  and rename this commit , you should add one next to the second commit r, or simply s replace it with  f:

pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
s b729ad5 fixup
s e3851e8 another fix

You can rename the commit in the text prompt box that pops up next.

Newer, awesomer features

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
#	modified:   README.md
#

If successful, you should see something similar to the following:

(main)$ Successfully rebased and updated refs/heads/main.

Safe merging strategy

--no-commit Perform a merge without autocommitting, giving the user a chance to review and modify before committing. no-ff It will leave evidence for the existence of the feature branch (feature branch), and keep the project history consistent (for more Git information, see How to complete the Git version rollback in IDEA? ).

(main)$ git merge --no-ff --no-commit my-branch

I need to merge a branch into a commit

(main)$ git merge --squash my-branch

I just want to combine (combine) the unpushed commit (unpushed commit)

Sometimes you have several work in progress commits before pushing the data upstream. At this time, you don't want to include the combinations that have been pushed, because others may already have commits that reference them.

(main)$ git rebase -i @{u}

This will generate an interactive rebase (interactive rebase), which will only list commits that have not been pushed. It is safe to reorder/fix/squash in this list.

Check if all commits on the branch have been merged

To check that all commits on one branch have been merged into other branches, you should do a diff between the heads (or any commits) of those branches:

(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll

This will give you a list of all commits that are in one branch but not in the other, and a list of commits that are not shared between branches. Another approach could be:

(main)$ git log main ^feature/120-on-scroll --no-merges

Possible problems with interactive rebase (interactive rebase)

This rebase edit screen appears 'noop'

If you see something like this:

noop

This means that your rebase branch is on the same commit as the current branch, or  ahead of  the current branch. You can try:

  • Check to make sure the main (main) branch is ok

  • rebase   HEAD~2 or earlier

conflict situation

If you cannot rebase successfully, you may have to resolve conflicts.

First execute  git status to find out which files are in conflict:

(my-branch)$ git status
On branch my-branch
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:   README.md

In this example,  README.md there is a conflict. Open this file and find something similar to the following:

<<<<<<< HEAD
   some code
   =========
   some code
   >>>>>>> new-commit

 You need to fix the difference between the newly submitted code (in the example, from the middle ==line to new-committhe place) and the new one.HEAD

Sometimes these merges are very complex and you should use the visual diff editor:

(main*)$ git mergetool -t opendiff

After you've resolved all conflicts and tested,  git add changed (changed) files, then git rebase --continue continue with rebase.

(my-branch)$ git add README.md
(my-branch)$ git rebase --continue

If after resolving all conflicts, you get the same result as before submitting, you can execute it git rebase --skip.

Anytime you want to end the whole rebase process and get back to the state of the branch before the rebase, you can do:

(my-branch)$ git rebase --abort

Stash

stage all changes

Staging all changes in your working directory

$ git stash

You can -uexclude some files with

$ git stash -u

Temporarily store specified files

Suppose you only want to temporarily store a certain file

$ git stash push working-directory-path/filename.ext

Suppose you want to stage multiple files

$ git stash push working-directory-path/filename1.ext working-directory-path/filename2.ext

Log messages while staging

so you can listsee it when

$ git stash save <message>

or

$ git stash push -m <message>

Use a specific cache

First you can view your stashrecords

$ git stash list

Then you can have applyastash

$ git stash apply "stash@{n}"

Here, 'n' is stashthe position in the stack, the top one stashwill be 0

In addition, time stamps can also be used (if you can remember).

$ git stash apply "stash@{2.hours.ago}"

Preserve unstaged content when staging

You need to manually create one stash commitand then use it git stash store.

$ git stash create
$ git stash store -m "commit-message" CREATED_SHA1

Miscellaneous Objects

clone all submodules

$ git clone --recursive git://github.com/foo/bar.git

If already cloned:

$ git submodule update --init --recursive

delete tag

$ git tag -d <tag_name>
$ git push <remote> :refs/tags/<tag_name>

Restore deleted tags (tag)

If you want to restore a deleted tag (tag), you can follow the steps below: First, you need to find the unreachable tag (unreachable tag):

$ git fsck --unreachable | grep tag

Write down the hash of this tag (tag), and then use Git's update-ref

$ git update-ref refs/tags/<tag_name> <hash>

At this point your tags should have been restored.

Removed patch

If someone sends you a pull request on GitHub, but then deletes his own original fork, you won't be able to clone or use their commit  git am. In this case, it's best to manually review their commits, copy them to a new local branch, and commit.

After submitting, modify the author, see Changing the author. Then, apply the changes, and issue a new pull request.

Tracking Files

I just want to change the case of a file name without modifying the content

(main)$ git mv --force myfile MyFile

I want to delete a file from Git but keep the file

(main)$ git rm --cached log.txt

Configuration

I want to add aliases to some Git commands

Under OS X and Linux, your Git configuration files are stored in  ~/.gitconfig. [alias] I added some shortcut aliases (and some that I tend to misspell) in the section, as follows:

[alias]
    a = add
    amend = commit --amend
    c = commit
    ca = commit --amend
    ci = commit -a
    co = checkout
    d = diff
    dc = diff --changed
    ds = diff --staged
    f = fetch
    loll = log --graph --decorate --pretty=oneline --abbrev-commit
    m = merge
    one = log --pretty=oneline
    outstanding = rebase -i @{u}
    s = status
    unpushed = log @{u}
    wc = whatchanged
    wip = rebase -i @{u}
    zap = fetch -p

I want to cache username and password for a repository

You may have a warehouse that requires authorization. At this time, you can cache the username and password instead of entering it every time you push/pull (push/pull). Credential helper can help you.

$ git config --global credential.helper cache
# Set git to use the credential memory cache
$ git config --global credential.helper 'cache --timeout=3600'
# Set the cache to timeout after 1 hour (setting is in seconds)

i don't know what i did wrong

You messed things up: you  重置(reset) broke something, or you merged the wrong branch, or you couldn't find your own commits after a push. There are times when you've been doing great all along, but you want to go back to something you were before.

This is  git reflog the purpose,  reflog to record any changes to the tip of a branch, even if that tip is not referenced by any branch or tag. Basically, every time HEAD changes, a new record is added to it reflog. Unfortunately, this only works on local branches, and it only tracks actions (for example, any changes to an unlogged file will not be tracked).

(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2

The reflog above shows a checkout from the main branch to the 2.2 branch, and then back again. There, there is also a hard reset to an older commit. The newest actions appear at the top for  HEAD@{0}identification.

If it turns out that you accidentally moved back (move back) the commit (commit), the reflog will contain the commit pointed to on main before you accidentally moved back (0254ea7).

$ git reset --hard 0254ea7

Then use git reset to change the main back to the previous commit, which provides a safety net in case the history is accidentally changed.

作者:小富
https://blog.csdn.net/xinzhifu1/article/details/123271097

Guess you like

Origin blog.csdn.net/Ed7zgeE9X/article/details/130143185