博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

Bash下的快捷操作

常用命令

  • cd:change directory 改变目录,bash中不带参数时默认进入【/c/Users/当前用户】目录,cmd中不带参数时等价于pwd
  • cd -:回到前一个目录,cmd中没有此命令
  • cd ..:回到父目录
  • cd aaa:进入指定目录,可以是相对目录或绝对目录
  • pwd:打印工作目录路径
  • lsll:列出当前目录中的所有文件,cmd中没有ll命令
  • touch aaa.txt:在当前目录下新建一个文件
  • mkdir aaa:在当前目录下新建一个目录
  • rm aaa.txt:删除指定的文件
  • rm -r aaa:删除指定的目录,参数r为recusive是递归的意思
  • mv aaa.txt bbb:将文件移到指定目录下
  • q:结束一个命令
  • explorer aa:打开指定的目录或文件

常用操作

  • 复制内容:选中后就已经复制了(勾选了"选择时复制"),或 Ctrl + Insert
  • 粘贴内容:点击鼠标中键,或 Shift + Insert
  • 搜索内容:Alt + F3,按EnterShift + Enter选中下/上一个匹配内容
  • 缩放文字:Ctrl + 【+/-】
  • 窗口清屏:Alt + F8(重置),cmd 下的命令是 cls【重要】
  • 窗口全屏:Alt + F11,再按一次还原

移动光标

  • 一个单词一个单词向左/右移动光标:Alt + B/F【重要】
  • 移动光标到整条命令的起始/结束位置:Ctrl + A/E【重要】
  • 一个字符一个字符向左/右移动光标:Ctrl + B/F

删除输入内容

  • 删除光标左/右侧的所有内容:Ctrl + U/K【重要】
  • 删除光标侧的单词:Ctrl + W【重要】
  • 删除光标侧的单词:Alt + D
  • 删除光标左/右侧的字符:Ctrl + H/D(或backspace键、delete键)

Tab键的作用

  • 输入内容(文件名或命令)的前几个字母时,按tab,如果有内容可以匹配,它就会显示出完整的内容
  • 如果有多个内容匹配到,它会显示最先找到的一个,再按一次tab,它就会匹配的下一个
  • 我们可以不停地按Tab键在匹配的内容中来回切换,直到找到我们文件名为止

Git默认Vim编辑器基本使用

Git默认的编辑器是Vim,在很多情境下会遇到它,例如commit提交,如果提供-m指令,直接在后面写上此次提交的说明信息;如果不提供-m指令,默认将会弹出Vim编辑器,如下:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.

此编辑器和平时所用编辑器差距很大,Vim编辑器命令很多,下面介绍一下简单操作,以完成基本的Git操作。

Vim主要有如下两种模式:

  • Normal 模式:命令模式,按 ESCCtrl + [ 进入,此模式下无法输入内容,但是可以复制、黏贴、保存、退出

    • :w表示保存
    • :q表示离开,如果未保存会有提示
    • :q!表示不保存离开
    • :wq表示保存并离开(用的最多)
  • Insert 模式:编辑模式,点击i、a 或 o 键可以进入

Git 使用场景

合并多个commit:rebase -i【s】

基本步骤

  • 执行git rebase -i HEAD~影响的最少commit数git rebase -i 前一个commitId
  • 需要合并的那条commit前面的pick改为s,保存后退出
  • 修改commit日志,保存后退出

详细操作

在使用 Git 作为版本控制的时候,我们可能会由于各种各样的原因提交了许多临时的 commit,而这些 commit 拼接起来才是完整的任务。那么我们为了避免太多的 commit 而造成版本控制的混乱,通常我们推荐将这些 commit 合并成一个。

首先你要知道自己想合并的是哪几个提交,可以使用 git log 命令来查看提交历史,假如最近 4 条历史如下:

commit 8b5cbda494a68582164048159e605e731f357444 (HEAD -> master)
commit a472755058e78a33595390f87d03d855fc25da84
commit 6ab13045d47157842961fae70baa7ef25e1856b1
commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)

历史记录是按照时间排序的,时间近的排在前面。

如果想要合并第 2 和第 3 条记录,有两个方法,这两个方法效果是一致的:

  • 从HEAD版本开始往过去数 3 个版本
git rebase -i HEAD~3
  • 指名要合并的版本之前的版本号
git rebase -i 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f

请注意 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f 这个版本是不参与合并的,可以把它当做一个坐标

执行了 rebase 命令之后,会弹出一个窗口,内容如下:

pick 6ab1304 11111111
pick a472755 222222222
pick 8b5cbda 3333333 # Rebase 00b8fe5..8b5cbda onto 00b8fe5 (3 commands)
#
# 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
# d, drop = remove commit
#
# 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(被注释掉的)

可以看到,里面有详细的命令提示。我们将需要合并的那条commit前面的pick改为s,之后保存并关闭文本编辑窗口即可。改完之后文本内容如下:

pick 6ab1304 11111111
s a472755 222222222
pick 8b5cbda 3333333

然后保存退出。如果没有冲突,或者冲突已经解决,则会出现如下的编辑窗口:

# This is a combination of 2 commits.
# This is the 1st commit message: 11111111 # This is the commit message #2: 222222222 # Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit(空消息会终止提交).
#
# Date: Sun Jul 7 21:14:02 2019 +0800
#
# interactive(互动) rebase in progress; onto 00b8fe5
# Last commands done (2 commands done):
# pick 6ab1304 11111111
# squash a472755 222222222
# Next command to do (1 remaining command):
# pick 8b5cbda 3333333
# You are currently rebasing branch 'master' on '00b8fe5'.
#
# Changes to be committed:
# modified: build.gradle

如果不做任何修改的话,默认是保留两次 commit 的日志,中间有一个空白行,你可以随意修改合并后的日志。

保存并退出后再次输入 git log 查看 commit 历史信息,你会发现这两个 commit 已经合并了。

commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (HEAD -> master)
commit 052ea3ea0b30c375e79ad9e891c5e5202768b11b
commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)

虽然我们只是合并了第 2 条和第 3 条的commit,但是第 1 条的 commitId 也变了。

如果有冲突,需要修改。修改的时候要注意,保留最新的历史,不然我们的修改就丢弃了。

修改以后要记得敲下面的命令:

git add .
git rebase --continue

如果你想放弃这次压缩的话,执行以下命令:

git rebase --abort

删除多个commit:rebase -i【d】

和上面的操作基本一致。

例如我的提交历史如下:

commit 831be8ec644c4943374adca03880732c7ec9d6bd (HEAD -> master)
commit 6a8ecb529a4ec6b6e0fc83e0789043b7785e73fe
commit 3b228d8af9e52806c106ef3f0c27e622b5407faf
commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (origin/master, origin/HEAD)

我想删除第2条和第3条提交,基本步骤:

  • 执行git rebase -i HEAD~影响的最少commit数git rebase -i 前一个commitId
  • 需要删除的那几条commit前面的pick改为d,保存后退出
  • 修改commit日志,保存后退出

注意,这个操作感觉出现冲突的概率比较大,例如我上面三次commit都是在同一个文件的第一行插入一行新的文字:

//添加3
//添加2
//添加1

执行rebase后就会提示冲突了:

git rebase -i 9adb987d31f11f8d38f8d817096d2d21a7390a1d
Auto-merging build.gradle
CONFLICT (content): Merge conflict in build.gradle
error: could not apply 831be8e... 333 Resolve all conflicts manually手动, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 831be8e... 333

解决冲突后按以下操作:

git add .
git rebase --continue

可以发现,相应 commit 都还原了,包括修改的文件以及提交的commit记录。

修改多个commit:rebase -i【r】

和上面的操作基本一致。

例如我的提交历史如下:

commit 442... (HEAD -> master)
commit 5a1...
commit 305...
commit f30... (origin/master, origin/HEAD)

我想修改第2条和第3条提交,基本步骤:

  • 执行git rebase -i HEAD~影响的最少commit数git rebase -i 前一个commitId
  • 需要修改的那几条commit前面的pick改为r,保存后退出
  • 每个改为reword的提交都会提示你一个编辑窗口让你修改commit日志,修改保存后退出

注意,修改后会生成新的commitId

挑选多个commit:cherry-pick

cherry-pick 的翻译是择优挑选,使用git cherry-pick命令,可以选择将现有的一个或者多个提交的修改引入当前内容。

cherry-pick 官方文档

git cherry-pick <commitid> <commitid>

挑选多个提交合并,提交之间用空格相隔。

git cherry-pick <start-commit>..<end-commit>

挑选一个范围内的多个提交合并,不包含start-commit(最早的提交),包含end-commit(最近的提交)。另外要注意两个 commit 之间要求有连续关系的,并且前者要在后者之前,顺序不能颠倒。

git cherry-pick <start-commit>^..<end-commit>

这个和上面一样,区别就是加了一个^符号,就变成闭区间了,包含 start-commit。

git cherry-pick <branch name>

挑选 branch 最顶端的提交。

git cherry-pick --continue  //继续下个操作
git cherry-pick --quit //退出
git cherry-pick --abort //停止本次操作

当 cherry-pick 多个 commit 时,假设遇到冲突:

  • --continue继续进行下个
  • --quit结束 cherry-pick 操作但是不会影响冲突之前多个提交中已经成功的
  • --abort直接打回原形,回到 cherry-pick 前的状态,包括多个提交中已经成功的

使用 git branch -d 删除分支的条件

参考:git branch -d 和 git branch -D 的区别

结论:在使用-d删除分支时,该分支必须完全和它的上游分支merge完成,如果没有上游分支,必须要和HEAD完全merge。

案例一

  • 1、现有一个本地分支 v0.1,我做一些修改后 commit (没有 commit或stash 是不能切换到其他分支的)
  • 2、然后切到其他分支(因为不能删除当前分支)后删除 v0.1 试试 ,可以发现删除失败
git branch -d v0.1
error: The branch 'v0.1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D v0.1'.

3、然后切到 v0.1 上,将修改推送到远端:git push origin v0.1

4、然后再切到其他分支后删除 v0.1 试试,可以发现删除成功,但是有警告

git branch -d v0.1
warning: deleting branch 'v0.1' that has been merged to 'refs/remotes/origin/v0.1', but not yet merged to HEAD.
Deleted branch v0.1 (was 4a79623).

上面的步骤进行一些优化:

4、假如我们后面删除前是切到了 master 分支,所以当前HEAD为 master 分支("所以"这个词用的对吗?)

5、将 v0.1 上的修改 merge 过来git merge v0.1,然后再删除 v0.1 试试,可以发现删除成功且没有警告

案例二

  • 1、首先我基于当前分支 v0.1 创建了一个分支 v0.1_copy:git branch v0.1_copy(此分支并没有上游分支)
  • 2、然后切到 v0.1_copy 上,并进行一些修改,然后 commit
  • 3、然后切到 v0.1 后删除 v0.1_copy 试试,可以发现删除失败
git branch -d v0.1_copy
error: The branch 'v0.1_copy' is not fully merged.
If you are sure you want to delete it, run 'git branch -D v0.1_copy'.

5、然后切到 v0.1 上,并将 v0.1_copy 上的修改 merge 过来git merge v0.1_copy

6、然后再删除 v0.1_copy 试试,可以发现删除成功且没有警告

git branch -d v0.1_copy
Deleted branch v0.1_copy (was 03cb1c6).

总结

简单来说就是这么一个设计思想:

  • 如果一个分支有和远端分支关联(有上游分支),那么在删除此分支前需要将此分支上的commit push到远端,不然在分支被删除时在其上所做的 commit 也一并被删除了,设计者认为这样的操作风险极大
  • 如果一个分支没有和远端分支关联(没有上游分支),由于在此分支上的 commit 不能 push 到远端,那么为了防止 commit 也一并被删除了,设计者要求必须要和HEAD完全merge才能删除

总之一句话,删除分支不能导致有任何已做的 commit 无法追踪,如果你想这么做,必须使用 -D 达到你的目的

解决 push 时提示 Everything up-to-date 问题

参考 stackoverflow 上的答案

问题复现

1、现在有一个本地分支 v0.1,且其和远端分支 v0.1 关联,此时你在本地 v0.1 做的任何修改都可以通过git push origin v0.1推到远端,这很正常

2、然后你通过git branch v0.1_backup创建了一个备份分支,然后 checkout 到此分支后做了一些修改,当你 commit 后 push 到远端的 v0.1 时问题就出现了

git push origin v0.1
Everything up-to-date

其实这里的 "Everything up-to-date(最新)", 的含义是:

"all the branches you've told me how to push are up to date".

也就是说远端的v0.1是最新的

并且此时其实并没有push到远端的

git status
On branch v0.1_backup
Your branch is ahead of 'origin/v0.1' by 1 commit.

原因是很简单的,分支 v0.1_backup 并没有和远端分支关联

$ git branch -vv
master de18ed6 [origin/master] 修改1
v0.1 03cb1c6 [origin/v0.1] 修改2
* v0.1_backup 88eb433 修改3

3、现在你通过git branch -u origin/v0.1 v0.1_backup可以将其和远端的 v0.1 关联

$ git branch -vv
master de18ed6 [origin/master] 修改1
v0.1 03cb1c6 [origin/v0.1] 修改2
* v0.1_backup 88eb433 [origin/v0.1: ahead 1] 修改3

4、然后再 push 到远端的 v0.1 会发现,问题依旧

解决方式

解决方式有三个:

1、改名,将本地分支名 v0.1_backup 改为和远程分支名一样的 v0.1 就可以了。神马,同名的分支已存在?那你为什么不在已存在的那个分支上操作呢?

2、merge,比如上面说的和远程分支同名的本地分支 v0.1 已存在时,可以先将 v0.1_backup 的修改 merge 到 v0.1 上,然后再在 v0.1 上 push 就可以了。虽然麻烦,但是这是标准操作(个人感觉)。

3、使用下面的命令也可以

git push origin v0.1_backup:v0.1

Author 与 Committer 有什么区别

参考

  • Author 是实际的修改者(patch 的作者),Committer 是提交者(把 patch 应用到 repository 里的人)
  • 很多项目限制只有少数人可以提交 patch,但大家(patch 的作者)都可以把 patch 发送给这些人
  • committer 只能通过 commit 得到,通过 git commit --reset-author 或者 --author="Name" 可以修改 Author(一般不会修改)

2019-7-14

-Git 使用技巧 总结 MD的更多相关文章

  1. git使用技巧

    git使用技巧 转载自:http://172.17.144.8/iceway.zhang/shares/201604/201604_git_tips.md.html 我们在工作中几乎每天都会用到git ...

  2. 七个你必须重视的 Git 使用技巧

    与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...

  3. 七个你无法忽视的Git使用技巧(转)

    与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...

  4. 七个你无法忽视的Git使用技巧

    与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...

  5. git使用技巧集合(持续更新中)

    git使用技巧集合(持续更新中) 在团队协作中,git.svn等工具是非常重要的,在此只记录一些git使用过程中遇到的问题以及解决方法,并且会持续更新. 1.git commit之后,还没push,如 ...

  6. Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具

    前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...

  7. Git 小技巧

    分享git的几个小技巧,后面会根据使用补充.目前包括git撤销本地修改.git回退到前n个版本.git多用户提交冲突解决.git 命令简化.欢迎大家补充^_* 1.git撤销本地修改 git rese ...

  8. 25个 Git 进阶技巧

    [ 原文] http://www.open-open.com/lib/view/open1431331496857.html 我已经使用git差不多18个月了,觉得自己对它应该已经非常了解.然后来自G ...

  9. git基本技巧及进阶

    基本技巧 1. 安装后的第一步 在安装好git后,你第一件该做的事是设置你的名字和电子邮箱,因为每次提交都要用到这些信息: $ git config --global user.name " ...

随机推荐

  1. Jenkins+SVN+Ant在Linux环境下自动完成版本的增量更新与编译

    第一步:查看安装的jdk版本,查看是否安装ant,查看是否安装Jenkins java -version ant -version rpm -qa|grep jenkins 第二步:安装ant 官网: ...

  2. xadmin引入celery4.0执行异步任务与定时任务

    一.安装 pip install celery pip install django-celery-beat pip install django-celery-results pip install ...

  3. GCN总结

    一.GCN简介 GNN模型主要研究图节点的表示(Graph Embedding),图边结构预测任务和图的分类问题,后两个任务也是基于Graph Embedding展开的.目前论文重点研究网络的可扩展性 ...

  4. VS操作中遇到的问题及解决

    1.无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中被引用 2. /ZI ...

  5. Oracle存储过程常用语法及其使用

    1.什么是存储过程 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行.它可以接受参数.输出参数,并可以返回单个或多个 ...

  6. 付哇刷脸支付系统源码V1.03完整安装包.zip

    付哇刷脸支付系统源码是什么? 1.是一款专业的刷脸+聚合支付平台源码系统: 2.支持对接自己的支付宝和微信官方服务商: 3.基于目前流行的WEB2.0的架构(php+mysql),采用自研DOXCX框 ...

  7. 从零和使用mxnet实现线性回归

    1.线性回归从零实现 from mxnet import ndarray as nd import matplotlib.pyplot as plt import numpy as np import ...

  8. PATA1055 The World's Richest (25 分)

    1055 The World's Richest (25 分) Forbes magazine publishes every year its list of billionaires based ...

  9. Android Studio 之 ROM【3】,LiveData+ViewModel+AsyncTask+Repository+RecyclerView

    教程地址:https://www.bilibili.com/video/av65180549 源码地址:https://github.com/longway777/Android-2019-Tutor ...

  10. 记C# 调用虹软人脸识别 那些坑

    上一个东家是从事安防行业的,致力于人工智能领域,有自主人脸识别.步态识别的算法.C++同事比较称职有什么问题都可以第一时间反馈,并得到合理的处理,封装的DLL 是基于更高性能的GPU算法,可支持更多线 ...