共计 14832 个字符,预计需要花费 38 分钟才能阅读完成。
大家好,我是小富~
技术交换关注公众号:程序员内点事
传送门:原文地址
git对于大家应该都不太生疏,纯熟应用 git 曾经成为程序员的一项基本技能,只管在工作中有诸如 Sourcetree
这样牛 X 的客户端工具,使得合并代码变的很不便。但找工作面试和一些需彰显集体实力的场景,依然须要咱们把握足够多的 git 命令。
下边咱们整顿了 45 个日常用 git 合代码的经典操作场景,根本笼罩了工作中的需要。
我方才提交了什么?
如果你用 git commit -a
提交了一次变动 (changes),而你又不确定到底这次提交了哪些内容。你就能够用上面的命令显示以后HEAD
上的最近一次的提交(commit):
(main)$ git show
或者
$ git log -n1 -p
我的提交信息 (commit message) 写错了
如果你的提交信息 (commit message) 写错了且这次提交 (commit) 还没有推(push), 你能够通过上面的办法来批改提交信息(commit message):
$ git commit --amend --only
这会关上你的默认编辑器, 在这里你能够编辑信息. 另一方面, 你也能够用一条命令一次实现:
$ git commit --amend --only -m 'xxxxxxx'
如果你曾经推 (push) 了这次提交 (commit), 你能够批改这次提交(commit) 而后强推(force push), 然而不举荐这么做。
我提交 (commit) 里的用户名和邮箱不对
如果这只是单个提交(commit),批改它:
$ git commit --amend --author "New Authorname <authoremail@mydomain.com>"
如果你须要批改所有历史, 参考 ‘git filter-branch’ 的指南页.
我想从一个提交 (commit) 里移除一个文件
通过上面的办法,从一个提交 (commit) 里移除一个文件:
$ git checkout HEAD^ myfile
$ git add -A
$ git commit --amend
这将十分有用,当你有一个凋谢的补丁 (open patch),你往上面提交了一个不必要的文件,你须要强推(force push) 去更新这个近程补丁。
我想删除我的的最初一次提交(commit)
如果你须要删除推了的提交 (pushed commits),你能够应用上面的办法。可是,这会不可逆的扭转你的历史,也会搞乱那些曾经从该仓库拉取(pulled) 了的人的历史。简而言之,如果你不是很确定,千万不要这么做。
$ git reset HEAD^ --hard
$ git push -f [remote] [branch]
如果你还没有推到近程, 把 Git 重置 (reset) 到你最初一次提交前的状态就能够了(同时保留暂存的变动):
(my-branch*)$ git reset --soft HEAD@{1}
这只能在没有推送之前有用. 如果你曾经推了, 惟一平安能做的是 git revert SHAofBadCommit
,那会创立一个新的提交 (commit) 用于吊销前一个提交的所有变动(changes);或者, 如果你推的这个分支是 rebase-safe 的 (例如:其它开发者不会从这个分支拉), 只须要应用 git push -f
。
删除任意提交(commit)
同样的正告:不到万不得已的时候不要这么做.
$ git rebase --onto SHA1_OF_BAD_COMMIT^ SHA1_OF_BAD_COMMIT
$ git push -f [remote] [branch]
或者做一个 交互式 rebase 删除那些你想要删除的提交 (commit) 里所对应的行。
我尝试推一个修改后的提交 (amended commit) 到近程,然而报错:
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.
留神, rebasing(见上面)和修改 (amending) 会用一个 新的提交 (commit) 代替旧的 , 所以如果之前你曾经往近程仓库上推过一次修改前的提交(commit),那你当初就必须强推(force push) (-f
)。留神 – 总是 确保你指明一个分支!
(my-branch)$ git push origin mybranch -f
一般来说, 要防止强推 . 最好是创立和推(push) 一个新的提交(commit),而不是强推一个修改后的提交。后者会使那些与该分支或该分支的子分支工作的开发者,在源历史中产生抵触。
我意外的做了一次硬重置(hard reset),我想找回我的内容
如果你意外的做了 git reset --hard
, 你通常能找回你的提交(commit), 因为 Git 对每件事都会有日志,且都会保留几天。
(main)$ git reflog
你将会看到一个你过来提交 (commit) 的列表, 和一个重置的提交。抉择你想要回到的提交 (commit) 的 SHA,再重置一次:
(main)$ git reset --hard SHA1234
这样就实现了。
暂存(Staging)
我须要把暂存的内容增加到上一次的提交(commit)
(my-branch*)$ git commit --amend
我想要暂存一个新文件的一部分,而不是这个文件的全副
一般来说, 如果你想暂存一个文件的一部分, 你可这样做:
$ git add --patch filename.x
-p
简写。这会关上交互模式,你将可能用 s
选项来分隔提交(commit);然而, 如果这个文件是新的, 会没有这个抉择,增加一个新文件时, 这样做:
$ git add -N filename.x
而后, 你须要用 e
选项来手动抉择须要增加的行,执行 git diff --cached
将会显示哪些行暂存了哪些行只是保留在本地了。
我想把在一个文件里的变动 (changes) 加到两个提交 (commit) 里
git add
会把整个文件退出到一个提交. git add -p
容许交互式的抉择你想要提交的局部.
我想把暂存的内容变成未暂存,把未暂存的内容暂存起来
少数状况下,你应该将所有的内容变为未暂存,而后再抉择你想要的内容进行 commit。
但假设你就是想要这么做,这里你能够创立一个长期的 commit 来保留你已暂存的内容,而后暂存你的未暂存的内容并进行 stash。而后 reset 最初一个 commit 将本来暂存的内容变为未暂存,最初 stash pop 回来。
$ git commit -m "WIP"
$ git add .
$ git stash
$ git reset HEAD^
$ git stash pop --index 0
留神 1: 这里应用 pop
仅仅是因为想尽可能放弃幂等。
留神 2: 如果你不加上 --index
你会把暂存的文件标记为为存储。
未暂存 (Unstaged) 的内容
我想把未暂存的内容挪动到一个新分支
$ git checkout -b my-branch
我想把未暂存的内容挪动到另一个已存在的分支
$ git stash
$ git checkout my-branch
$ git stash pop
我想抛弃本地未提交的变动(uncommitted changes)
如果你只是想重置源 (origin) 和你本地 (local) 之间的一些提交(commit),你能够:
# 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
重置某个非凡的文件, 你能够用文件名做为参数:
$ git reset filename
我想抛弃某些未暂存的内容
如果你想抛弃工作拷贝中的一部分内容,而不是全副。
签出 (checkout) 不须要的内容,保留须要的。
$ git checkout -p
# Answer y to all of the snippets you want to drop
另外一个办法是应用 stash
,Stash 所有要保留下的内容, 重置工作拷贝, 从新利用保留的局部。
$ git stash -p
# Select all of the snippets you want to save
$ git reset --hard
$ git stash pop
或者, stash 你不须要的局部, 而后 stash drop。
$ git stash -p
# Select all of the snippets you don't want to save
$ git stash drop
分支(Branches)
我从谬误的分支拉取了内容,或把内容拉取到了谬误的分支
这是另外一种应用 git reflog
状况,找到在这次谬误拉(pull) 之前 HEAD 的指向。
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
重置分支到你所需的提交(desired commit):
$ git reset --hard c5bc55a
实现。
我想扔掉本地的提交(commit),以便我的分支与近程的保持一致
先确认你没有推 (push) 你的内容到近程。
git status
会显示你当先 (ahead) 源(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)
#
一种办法是:
(main)$ git reset --hard origin/my-branch
我须要提交到一个新分支,但谬误的提交到了 main
在 main 下创立一个新分支,不切换到新分支, 仍在 main 下:
(main)$ git branch my-branch
把 main 分支重置到前一个提交:
(main)$ git reset --hard HEAD^
HEAD^
是 HEAD^1
的简写,你能够通过指定要设置的 HEAD
来进一步重置。
或者, 如果你不想应用 HEAD^
, 找到你想重置到的提交 (commit) 的 hash(git log
可能实现),而后重置到这个 hash。应用git push
同步内容到近程。
例如, main 分支想重置到的提交的 hash 为a13b85e
:
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
签出 (checkout) 方才新建的分支持续工作:
(main)$ git checkout my-branch
我想保留来自另外一个 ref-ish 的整个文件
假如你正在做一个原型计划(原文为 working spike (see note)), 有成百的内容,每个都工作得很好。当初, 你提交到了一个分支,保留工作内容:
(solution)$ git add -A && git commit -m "Adding all changes from this spike into one big commit."
当你想要把它放到一个分支里 (可能是feature
, 或者 develop
), 你关怀是放弃整个文件的残缺,你想要一个大的提交分隔成比拟小。
假如你有:
- 分支
solution
, 领有原型计划,当先develop
分支。 - 分支
develop
, 在这里你利用原型计划的一些内容。
我去能够通过把内容拿到你的分支里,来解决这个问题:
(develop)$ git checkout solution -- file1.txt
这会把这个文件内容从分支 solution
拿到分支 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
而后, 失常提交。
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.
我把几个提交 (commit) 提交到了同一个分支,而这些提交应该散布在不同的分支里
假如你有一个 main
分支,执行git log
, 你看到你做过两次提交:
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
Date: Tue Jul 22 15:39:27 2014 -0400
Bug #21 - Added CSRF protection
commit 5ea51731d150f7ddc4a365437931cd8be3bf3131
Author: Alex Lee <alexlee@example.com>
Date: Tue Jul 22 15:39:12 2014 -0400
Bug #14 - Fixed spacing on title
commit a13b85e984171c6e2a1729bb061994525f626d14
Author: Aki Rose <akirose@example.com>
Date: Tue Jul 21 01:12:48 2014 -0400
First commit
让咱们用提交 hash(commit hash)标记 bug (e3851e8
for #21, 5ea5173
for #14).
首先, 咱们把 main
分支重置到正确的提交(a13b85e
):
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
当初, 咱们对 bug #21 创立一个新的分支:
(main)$ git checkout -b 21
(21)$
接着, 咱们用 cherry-pick 把对 bug #21 的提交放入以后分支。这意味着咱们将利用 (apply) 这个提交(commit),仅仅这一个提交(commit),间接在 HEAD 下面。
(21)$ git cherry-pick e3851e8
这时候, 这里可能会产生抵触,参见交互式 rebasing 章 抵触节 解决抵触.
再者,咱们为 bug #14 创立一个新的分支, 也基于 main
分支
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
最初, 为 bug #14 执行 cherry-pick
:
(14)$ git cherry-pick 5ea5173
我想删除上游 (upstream) 分支被删除了的本地分支
一旦你在 github 下面合并 (merge) 了一个 pull request, 你就能够删除你 fork 里被合并的分支。如果你不筹备持续在这个分支里工作, 删除这个分支的本地拷贝会更洁净,使你不会陷入工作分支和一堆古老分支的凌乱之中。
$ git fetch -p
我不小心删除了我的分支
如果你定期推送到近程, 少数状况下应该是平安的,但有些时候还是可能删除了还没有推到近程的分支。让咱们先创立一个分支和一个新的文件:
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
README.md foo.txt
增加文件并做一次提交
(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 <siemiatj@example.com>
Date: Wed Jul 30 00:34:10 2014 +0200
foo.txt added
commit 69204cdf0acbab201619d95ad8295928e7f411d5
Author: Kate Hudson <katehudson@example.com>
Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
当初咱们切回到主 (main) 分支,‘不小心的’删除 my-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!
在这时候你应该想起了 reflog
, 一个升级版的日志,它存储了仓库(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
正如你所见,咱们有一个来自删除分支的提交 hash(commit hash),接下来看看是否能复原删除了的分支。
(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
看! 咱们把删除的文件找回来了。Git 的 reflog
在 rebasing 出错的时候也是同样有用的。
我想删除一个分支
删除一个近程分支:
(main)$ git push origin --delete my-branch
你也能够:
(main)$ git push origin :my-branch
删除一个本地分支:
(main)$ git branch -D my-branch
我想从他人正在工作的近程分支签出 (checkout) 一个分支
首先, 从近程拉取(fetch) 所有分支:
(main)$ git fetch --all
假如你想要从近程的 daves
分支签出到本地的daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
(--track
是 git checkout -b [branch] [remotename]/[branch]
的简写)
这样就失去了一个 daves
分支的本地拷贝, 任何推过 (pushed) 的更新,近程都能看到.
Rebasing 和合并(Merging)
我想撤销 rebase/merge
你能够合并 (merge) 或 rebase 了一个谬误的分支, 或者实现不了一个进行中的 rebase/merge。Git 在进行危险操作的时候会把原始的 HEAD 保留在一个叫 ORIG_HEAD 的变量里, 所以要把分支复原到 rebase/merge 前的状态是很容易的。
(my-branch)$ git reset --hard ORIG_HEAD
我曾经 rebase 过, 然而我不想强推(force push)
可怜的是,如果你想把这些变动 (changes) 反馈到近程分支上,你就必须得强推 (force push)。是因你快进(Fast forward) 了提交,扭转了 Git 历史, 近程分支不会承受变动 (changes),除非强推(force push)。这就是许多人应用 merge 工作流, 而不是 rebasing 工作流的次要起因之一,开发者的强推(force push) 会使大的团队陷入麻烦。应用时须要留神,一种平安应用 rebase 的办法是,不要把你的变动 (changes) 反映到近程分支上, 而是按上面的做:
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
我须要组合 (combine) 几个提交(commit)
假如你的工作分支将会做对于 main
的 pull-request。个别状况下你不关怀提交 (commit) 的工夫戳,只想组合 所有 提交(commit) 到一个独自的外面, 而后重置(reset) 重提交 (recommit)。确保主(main) 分支是最新的和你的变动都曾经提交了, 而后:
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
如果你想要更多的管制, 想要保留工夫戳, 你须要做交互式 rebase (interactive rebase):
(my-branch)$ git rebase -i main
如果没有绝对的其它分支,你将不得不绝对本人的HEAD
进行 rebase。例如:你想组合最近的两次提交(commit), 你将绝对于HEAD~2
进行 rebase,组合最近 3 次提交(commit), 绝对于HEAD~3
, 等等。
(main)$ git rebase -i HEAD~2
在你执行了交互式 rebase 的命令 (interactive rebase command) 后, 你将在你的编辑器里看到相似上面的内容:
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
所有以 #
结尾的行都是正文, 不会影响 rebase.
而后,你能够用任何下面命令列表的命令替换 pick
, 你也能够通过删除对应的行来删除一个提交(commit)。
例如, 如果你想 独自保留最旧 (first) 的提交 (commit), 组合所有剩下的到第二个外面, 你就应该编辑第二个提交(commit) 前面的每个提交(commit) 前的单词为 f
:
pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
f b729ad5 fixup
f e3851e8 another fix
如果你想组合这些提交 (commit) 并重命名这个提交 (commit), 你应该在第二个提交(commit) 旁边增加一个r
,或者更简略的用s
代替 f
:
pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
s b729ad5 fixup
s e3851e8 another fix
你能够在接下来弹出的文本提示框里重命名提交(commit)。
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
#
如果胜利了, 你应该看到相似上面的内容:
(main)$ Successfully rebased and updated refs/heads/main.
平安合并 (merging) 策略
--no-commit
执行合并 (merge) 但不主动提交, 给用户在做提交前检查和批改的机会。no-ff
会为个性分支 (feature branch) 的存在过留下证据, 放弃我的项目历史统一。
(main)$ git merge --no-ff --no-commit my-branch
我须要将一个分支合并成一个提交(commit)
(main)$ git merge --squash my-branch
我只想组合 (combine) 未推的提交(unpushed commit)
有时候,在将数据推向上游之前,你有几个正在进行的工作提交 (commit)。这时候不心愿把曾经推(push) 过的组合进来,因为其他人可能曾经有提交 (commit) 援用它们了。
(main)$ git rebase -i @{u}
这会产生一次交互式的 rebase(interactive rebase), 只会列出没有推 (push) 的提交(commit),在这个列表时进行 reorder/fix/squash 都是平安的。
查看是否分支上的所有提交 (commit) 都合并 (merge) 过了
查看一个分支上的所有提交 (commit) 是否都曾经合并 (merge) 到了其它分支, 你应该在这些分支的 head(或任何 commits)之间做一次 diff:
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
这会通知你在一个分支里有而另一个分支没有的所有提交 (commit), 和分支之间不共享的提交(commit) 的列表。另一个做法能够是:
(main)$ git log main ^feature/120-on-scroll --no-merges
交互式 rebase(interactive rebase)可能呈现的问题
这个 rebase 编辑屏幕呈现 ’noop’
如果你看到的是这样:
noop
这意味着你 rebase 的分支和以后分支在同一个提交 (commit) 上, 或者 当先(ahead) 以后分支。你能够尝试:
- 查看确保主 (main) 分支没有问题
- rebase
HEAD~2
或者更早
有抵触的状况
如果你不能胜利的实现 rebase, 你可能必须要解决抵触。
首先执行 git status
找出哪些文件有抵触:
(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
在这个例子外面, README.md
有抵触。关上这个文件找到相似上面的内容:
<<<<<<< HEAD
some code
=========
some code
>>>>>>> new-commit
你须要解决新提交的代码 (示例里, 从两头==
线到 new-commit
的中央)与HEAD
之间不一样的中央.
有时候这些合并非常复杂,你应该应用可视化的差别编辑器(visual diff editor):
(main*)$ git mergetool -t opendiff
在你解决完所有抵触和测试过后, git add
变动了的 (changed) 文件, 而后用git rebase --continue
持续 rebase。
(my-branch)$ git add README.md
(my-branch)$ git rebase --continue
如果在解决完所有的抵触过后,失去了与提交前一样的后果, 能够执行git rebase --skip
。
任何时候你想完结整个 rebase 过程,回来 rebase 前的分支状态, 你能够做:
(my-branch)$ git rebase --abort
Stash
暂存所有改变
暂存你工作目录下的所有改变
$ git stash
你能够应用 -u
来排除一些文件
$ git stash -u
暂存指定文件
假如你只想暂存某一个文件
$ git stash push working-directory-path/filename.ext
假如你想暂存多个文件
$ git stash push working-directory-path/filename1.ext working-directory-path/filename2.ext
暂存时记录音讯
这样你能够在 list
时看到它
$ git stash save <message>
或
$ git stash push -m <message>
应用某个指定暂存
首先你能够查看你的 stash
记录
$ git stash list
而后你能够 apply
某个stash
$ git stash apply "stash@{n}"
此处,‘n’ 是 stash
在栈中的地位,最上层的 stash
会是 0
除此之外,也能够应用工夫标记(如果你能记得的话)。
$ git stash apply "stash@{2.hours.ago}"
暂存时保留未暂存的内容
你须要手动 create 一个stash commit
,而后应用git stash store
。
$ git stash create
$ git stash store -m "commit-message" CREATED_SHA1
杂项(Miscellaneous Objects)
克隆所有子模块
$ git clone --recursive git://github.com/foo/bar.git
如果曾经克隆了:
$ git submodule update --init --recursive
删除标签(tag)
$ git tag -d <tag_name>
$ git push <remote> :refs/tags/<tag_name>
复原已删除标签(tag)
如果你想复原一个已删除标签(tag), 能够依照上面的步骤: 首先, 须要找到无法访问的标签(unreachable tag):
$ git fsck --unreachable | grep tag
记下这个标签 (tag) 的 hash,而后用 Git 的 update-ref
$ git update-ref refs/tags/<tag_name> <hash>
这时你的标签 (tag) 应该曾经复原了。
已删除补丁(patch)
如果某人在 GitHub 上给你发了一个 pull request, 然而而后他删除了他本人的原始 fork, 你将没法克隆他们的提交 (commit) 或应用 git am
。在这种状况下, 最好手动的查看他们的提交(commit),并把它们拷贝到一个本地新分支,而后做提交。
做完提交后, 再批改作者,参见变更作者。而后, 利用变动, 再发动一个新的 pull request。
跟踪文件(Tracking Files)
我只想扭转一个文件名字的大小写,而不批改内容
(main)$ git mv --force myfile MyFile
我想从 Git 删除一个文件,但保留该文件
(main)$ git rm --cached log.txt
配置(Configuration)
我想给一些 Git 命令增加别名(alias)
在 OS X 和 Linux 下, 你的 Git 的配置文件贮存在 ~/.gitconfig
。我在[alias]
局部增加了一些快捷别名(和一些我容易拼写错误的),如下:
[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
我想缓存一个仓库 (repository) 的用户名和明码
你可能有一个仓库须要受权,这时你能够缓存用户名和明码,而不必每次推 / 拉 (push/pull) 的时候都输出,Credential helper 能帮你。
$ 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)
我不晓得我做错了些什么
你把事件搞砸了:你 重置 (reset)
了一些货色, 或者你合并了谬误的分支, 亦或你强推了后找不到你本人的提交(commit) 了。有些时候, 你始终都做得很好, 但你想回到以前的某个状态。
这就是 git reflog
的目标,reflog
记录对分支顶端 (the tip of a branch) 的任何扭转, 即便那个顶端没有被任何分支或标签援用。基本上, 每次 HEAD 的扭转, 一条新的记录就会减少到reflog
。遗憾的是,这只对本地分支起作用,且它只跟踪动作 (例如,不会跟踪一个没有被记录的文件的任何扭转)。
(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
下面的 reflog 展现了从 main 分支签出 (checkout) 到 2.2 分支,而后再签回。那里,还有一个硬重置 (hard reset) 到一个较旧的提交。最新的动作呈现在最下面以 HEAD@{0}
标识.
如果事实证明你不小心回移 (move back) 了提交(commit), reflog 会蕴含你不小心回移前 main 上指向的提交(0254ea7)。
$ git reset --hard 0254ea7
而后应用 git reset 就能够把 main 改回到之前的 commit,这提供了一个在历史被意外更改状况下的安全网。
技术交换关注公众号:程序员内点事
传送门:原文地址