【git】git基础总结与SourceTree的使用和配置

目录

  • 1 终端使用git
    • 1.1 安装git
      • 1.1.1 配置git bash
      • 1.1.2 终端命令
      • 1.1.3 git命令关键字
      • 1.1.4 git名词介绍
    • 1.2 暂存区
      • 1.2.1 #init 创建本地版本库
      • 1.2.2 #status 比较工作区和暂存区的差异
        • 1.2.2.1 解决status中文乱码问题
      • 1.2.3 #add 提交文件到暂存区
      • 1.2.4 查看暂存区的内容 #ls-files
        • 1.2.4.1 删除暂存区内的文件,删除远端分支的文件 #rm #cached
      • 1.2.5 移动、重命名已跟踪的文件 #mv
    • 1.3 本地版本库
      • 1.3.1 #commit 提交文件修改操作到本地版本库
        • 1.3.1.1 git commit -m和git commit -am的区别
        • 1.3.1.2 提交无改动版本
      • 1.3.2 #log 查看所有分支的提交日志
      • 1.3.3 #show 比较当前和上一次提交的内容
        • 1.3.3.1 例子
      • 1.3.4 #gitignore 让文件不被跟踪
        • 1.3.4.1 glob 模式匹配规则
      • 1.3.5 #reset 回滚到任意指定版本
        • 1.3.5.1 硬合并,重置工作区 #hard
        • 1.3.5.2 混合合并,工作区不变 #mixed
        • 1.3.5.3 软合并,工作区不变 #sort
      • 1.3.6 #reflog 查看head指针的移动轨迹,查看历史版本号
      • 1.3.7 更新本地代码 #pull #fetch
        • 1.3.7.1 例子:fetch+merge更新代码,pull的默认更新方式
        • 1.3.7.2 pull使用rebase方式更新代码,推荐 #rebase
      • 1.3.8 贮藏已跟踪文件的修改操作 #stash
    • 1.4 远端仓库
      • 1.4.1 远端仓库配置ssh公钥,推荐ssh拉取代码
        • 1.4.1.1 生成ssh公钥 #ssh-keygen
        • 1.4.1.2 github添加生成的ssh公钥
      • 1.4.2 克隆远端仓库到本地版本库 #clone
      • 1.4.3 例子:推送本地项目到远端仓库
      • 1.4.4 #config 项目git配置信息
        • 1.4.4.1 标记提交代码的开发者身份
        • 1.4.4.2 全局配置 #global
        • 1.4.4.3 局部配置,设置仓库的开发者身份 #local
        • 1.4.4.4 编辑器修改配置
      • 1.4.5 #origin 远端仓库地址
        • 1.4.5.1 远端仓库地址 #remote
        • 1.4.5.2 设置本地分支的跟踪关系,使用origin简写
      • 1.4.6 #push 把本地分支内容推送到指定的远端分支
        • 1.4.6.1 例子
        • 1.4.6.2 推送代码前,必须先更新代码 #pull
        • 1.4.6.3 强制推送,强制覆盖远端分支
        • 1.4.6.4 回滚远端分支的版本
          • 1.4.6.4.1 方式一:推送修改操作,回滚远端分支,推荐 #soft #reset
          • 1.4.6.4.2 方式二:强制推送覆盖远端分支,不推荐
      • 1.4.7 发起合并请求 pull request #PR
        • 1.4.7.1 例子:合并自己的远端分支
          • 1.4.7.1.1 处理合并请求 #rebase #merge
        • 1.4.7.2 例子:请求别人的远端分支合并自己的远端分支 #fork
        • 1.4.7.3 回滚指定pr的修改操作 #revert
      • 1.4.8 删除远端分支
    • 1.5 本地分支管理
      • 1.5.1 #branch 查看分支,生成本地分支的快照
        • 1.5.1.1 创建新分支
        • 1.5.1.2 强制删除指定分支 `-D`
        • 1.5.1.3 恢复被删掉的本地分支
      • 1.5.2 #checkout 检出到指定分支
        • 1.5.2.1 在指定版本创建分支并切换
        • 1.5.2.2 创建并签出到分支,并指定跟踪关系
        • 1.5.2.3 通过贮藏处理签出冲突 #stash
        • 1.5.2.4 签出远端分支
      • 1.5.3 #merge 合并分支,生成新结点
        • 1.5.3.1 例子:无分叉merge,快速移动 #Fast-forward
        • 1.5.3.2 例子:有分叉merge(理解merge操作)
          • 1.5.3.2.1 对比`merge`和`rebase` #rebase
        • 1.5.3.3 例子:手动处理合并冲突 #冲突
        • 1.5.3.4 放弃合并
      • 1.5.4 #diff 比较文件内容差异
        • 1.5.4.1 例子:比较工作区和暂存区`ls-files`
        • 1.5.4.2 例子:比较工作区和指定版本
        • 1.5.4.3 例子:比较暂存区`ls-files`和指定版本 #cached #staged
        • 1.5.4.4 例子:比较不同版本
      • 1.5.5 丢弃文件的修改操作 #restore #stash
      • 1.5.6 #rebase #变基 指定修改起点,迁移所有修改操作到指定分支
        • 1.5.6.1 例子
        • 1.5.6.2 例子:没有使用rebase
        • 1.5.6.3 例子:使用rebase,指定修改起点
      • 1.5.7 #cherry-pick #优选 复用其他分支的提交内容
  • 2 SourceTree使用git
    • 2.1 配置
      • 2.1.1 添加ssh公钥
      • 2.1.2 设置默认克隆项目位置
    • 2.2 克隆项目 #clone
    • 2.3 添加到暂存区 #add
    • 2.4 推送到本地版本库 #commit
    • 2.5 更新代码 #pull
      • 2.5.1 merge方式更新代码
      • 2.5.2 rebase方式更新代码
    • 2.6 推送本地分支到远端分支 #pull #push
    • 2.7 切换本地分支,拉取远端分支 #checkout
    • 2.8 新建分支 #checkout #branch
    • 2.9 合并分支 #merge
      • 2.9.1 例子:手动解决冲突
      • 2.9.2 冲突比较工具:BeyondCompare
        • 2.9.2.1 配置
        • 2.9.2.2 例子
    • 2.10 贮藏已跟踪文件的修改操作 #stash
    • 2.11 变基 #rebase
    • 2.12 在日志中查找指定版本
      • 2.12.1 例子:查找某个人的提交记录
    • 2.13 回滚工作区到指定版本 #reset


【git】git基础总结与SourceTree的使用和配置_第1张图片

1 终端使用git

1.1 安装git

git bash中可以使用linux命令来操作windows系统

官网下载git

  • linux安装git
yum install git

1.1.1 配置git bash

【git】git基础总结与SourceTree的使用和配置_第2张图片

1.1.2 终端命令

右键目录+s可以快速打开bash

                   SUMMARY OF LESS COMMANDS

      Commands marked with * may be preceded by a number, N.
      Notes in parentheses indicate the behavior if N is given.
      A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.

  h  H                 Display this help.
  q  :q  Q  :Q  ZZ     Exit.
 ---------------------------------------------------------------------------

                           MOVING

  e  ^E  j  ^N  CR  *  Forward  one line   (or N lines).
  y  ^Y  k  ^K  ^P  *  Backward one line   (or N lines).
  f  ^F  ^V  SPACE  *  Forward  one window (or N lines).
  b  ^B  ESC-v      *  Backward one window (or N lines).
  z                 *  Forward  one window (and set window to N).
  w                 *  Backward one window (and set window to N).
  ESC-SPACE         *  Forward  one window, but don't stop at end-of-file.
  d  ^D             *  Forward  one half-window (and set half-window to N).
  u  ^U             *  Backward one half-window (and set half-window to N).
  ESC-)  RightArrow *  Right one half screen width (or N positions).
  ESC-(  LeftArrow  *  Left  one half screen width (or N positions).
  ESC-}  ^RightArrow   Right to last column displayed.
  ESC-{  ^LeftArrow    Left  to first column.
  F                    Forward forever; like "tail -f".
  ESC-F                Like F but stop when search pattern is found.
  r  ^R  ^L            Repaint screen.
  R                    Repaint screen, discarding buffered input.
        ---------------------------------------------------
        Default "window" is the screen height.
        Default "half-window" is half of the screen height.
 ---------------------------------------------------------------------------

                          SEARCHING

  /pattern          *  Search forward for (N-th) matching line.
  ?pattern          *  Search backward for (N-th) matching line.
  n                 *  Repeat previous search (for N-th occurrence).
  N                 *  Repeat previous search in reverse direction.
  ESC-n             *  Repeat previous search, spanning files.
  ESC-N             *  Repeat previous search, reverse dir. & spanning files.
  ESC-u                Undo (toggle) search highlighting.
  &pattern          *  Display only matching lines
        ---------------------------------------------------
        A search pattern may begin with one or more of:
        ^N or !  Search for NON-matching lines.
        ^E or *  Search multiple files (pass thru END OF FILE).
        ^F or @  Start search at FIRST file (for /) or last file (for ?).
        ^K       Highlight matches, but don't move (KEEP position).
        ^R       Don't use REGULAR EXPRESSIONS.
 ---------------------------------------------------------------------------

                           JUMPING

  g  <  ESC-<       *  Go to first line in file (or line N).
  G  >  ESC->       *  Go to last line in file (or line N).
  p  %              *  Go to beginning of file (or N percent into file).
  t                 *  Go to the (N-th) next tag.
  T                 *  Go to the (N-th) previous tag.
  {  (  [           *  Find close bracket } ) ].
  }  )  ]           *  Find open bracket { ( [.
  ESC-^F    *  Find close bracket .
  ESC-^B    *  Find open bracket  
        ---------------------------------------------------
        Each "find close bracket" command goes forward to the close bracket 
          matching the (N-th) open bracket in the top line.
        Each "find open bracket" command goes backward to the open bracket 
          matching the (N-th) close bracket in the bottom line.

  m            Mark the current top line with .
  M            Mark the current bottom line with .
  '<letter>            Go to a previously marked position.
  ''                   Go to the previous position.
  ^X^X                 Same as '.
  ESC-M        Clear a mark.
        ---------------------------------------------------
        A mark is any upper-case or lower-case letter.
        Certain marks are predefined:
             ^  means  beginning of the file
             $  means  end of the file
---------------------------------------------------------------------------

                        CHANGING FILES

  :e [file]            Examine a new file.
  ^X^V                 Same as :e.
  :n                *  Examine the (N-th) next file from the command line.
  :p                *  Examine the (N-th) previous file from the command line.
  :x                *  Examine the first (or N-th) file from the command line.
  :d                   Delete the current file from the command line list.
  =  ^G  :f            Print current file name.
 ---------------------------------------------------------------------------

                    MISCELLANEOUS COMMANDS

  -              Toggle a command line option [see OPTIONS below].
  --             Toggle a command line option, by name.
  _              Display the setting of a command line option.
  __             Display the setting of an option, by name.
  +cmd                 Execute the less cmd each time a new file is examined.

  !command             Execute the shell command with $SHELL.
  |Xcommand            Pipe file between current pos & mark X to shell command.
  s file               Save input to a file.
  v                    Edit the current file with $VISUAL or $EDITOR.
  V                    Print version number of "less".
 ---------------------------------------------------------------------------

                           OPTIONS

        Most options may be changed either on the command line,
        or from within less by using the - or -- command.
        Options may be given in one of two forms: either a single
        character preceded by a -, or a name preceded by --.

  -?  ........  --help
                  Display help (from command line).
  -a  ........  --search-skip-screen
                  Search skips current screen.
  -A  ........  --SEARCH-SKIP-SCREEN
                  Search starts just after target line.
  -b [N]  ....  --buffers=[N]
                  Number of buffers.
  -B  ........  --auto-buffers
                  Don't automatically allocate buffers for pipes.
  -c  ........  --clear-screen
                  Repaint by clearing rather than scrolling.
  -d  ........  --dumb
                  Dumb terminal.
  -D [xn.n]  .  --color=xn.n
                  Set screen colors. (MS-DOS only)
  -e  -E  ....  --quit-at-eof  --QUIT-AT-EOF
                  Quit at end of file.
  -f  ........  --force
                  Force open non-regular files.
  -F  ........  --quit-if-one-screen
                  Quit if entire file fits on first screen.
  -g  ........  --hilite-search
                  Highlight only last match for searches.
  -G  ........  --HILITE-SEARCH
                  Don't highlight any matches for searches.
  -h [N]  ....  --max-back-scroll=[N]
                  Backward scroll limit.
  -i  ........  --ignore-case
                  Ignore case in searches that do not contain uppercase.
  -I  ........  --IGNORE-CASE
                  Ignore case in all searches.
  -j [N]  ....  --jump-target=[N]
                  Screen position of target lines.
  -J  ........  --status-column
                  Display a status column at left edge of screen.
  -k [file]  .  --lesskey-file=[file]
                  Use a lesskey file.
  -K  ........  --quit-on-intr
                  Exit less in response to ctrl-C.
  -L  ........  --no-lessopen
                  Ignore the LESSOPEN environment variable.
  -m  -M  ....  --long-prompt  --LONG-PROMPT
                  Set prompt style.
  -n  -N  ....  --line-numbers  --LINE-NUMBERS
                  Don't use line numbers.
  -o [file]  .  --log-file=[file]
                  Copy to log file (standard input only).
  -O [file]  .  --LOG-FILE=[file]
                  Copy to log file (unconditionally overwrite).
  -p [pattern]  --pattern=[pattern]
                  Start at pattern (from command line).
  -P [prompt]   --prompt=[prompt]
                  Define new prompt.
  -q  -Q  ....  --quiet  --QUIET  --silent --SILENT
                  Quiet the terminal bell.
  -r  -R  ....  --raw-control-chars  --RAW-CONTROL-CHARS
  -s  ........  --squeeze-blank-lines
                  Squeeze multiple blank lines.
  -S  ........  --chop-long-lines
                  Chop (truncate) long lines rather than wrapping.
  -t [tag]  ..  --tag=[tag]
                  Find a tag.
  -T [tagsfile] --tag-file=[tagsfile]
                  Use an alternate tags file.
  -u  -U  ....  --underline-special  --UNDERLINE-SPECIAL
                  Change handling of backspaces.
  -V  ........  --version
                  Display the version number of "less".
  -w  ........  --hilite-unread
                  Highlight first new line after forward-screen.
  -W  ........  --HILITE-UNREAD
                  Highlight first new line after any forward movement.
  -x [N[,...]]  --tabs=[N[,...]]
                  Set tab stops.
  -X  ........  --no-init
                  Don't use termcap init/deinit strings.
  -y [N]  ....  --max-forw-scroll=[N]
                  Forward scroll limit.
  -z [N]  ....  --window=[N]
                  Set size of window.
  -" [c[c]]  .  --quotes=[c[c]]
                  Set shell quote characters.
  -~  ........  --tilde
                  Don't display tildes after end of file.
  -# [N]  ....  --shift=[N]
                  Horizontal scroll amount (0 = one half screen width)
                --follow-name
                  The F command changes files if the input file is renamed.
                --mouse
                  Enable mouse input.
                --no-keypad
                  Don't send termcap keypad init/deinit strings.
                --no-histdups
                  Remove duplicates from command history.
                --rscroll=C
                  Set the character used to mark truncated lines.
                --save-marks
                  Retain marks across invocations of less.
                --use-backslash
                  Subsequent options use backslash as escape char.
                --wheel-lines=N
                  Each click of the mouse wheel moves N lines.


 ---------------------------------------------------------------------------

                          LINE EDITING

        These keys can be used to edit text being entered 
        on the "command line" at the bottom of the screen.

 RightArrow ..................... ESC-l ... Move cursor right one character.
 LeftArrow ...................... ESC-h ... Move cursor left one character.
 ctrl-RightArrow  ESC-RightArrow  ESC-w ... Move cursor right one word.
 ctrl-LeftArrow   ESC-LeftArrow   ESC-b ... Move cursor left one word.
 HOME ........................... ESC-0 ... Move cursor to start of line.
 END ............................ ESC-$ ... Move cursor to end of line.
 BACKSPACE ................................ Delete char to left of cursor.
 DELETE ......................... ESC-x ... Delete char under cursor.
 ctrl-BACKSPACE   ESC-BACKSPACE ........... Delete word to left of cursor.
 ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
 ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
 UpArrow ........................ ESC-k ... Retrieve previous command line.
 DownArrow ...................... ESC-j ... Retrieve next command line.
 TAB ...................................... Complete filename & cycle.
 SHIFT-TAB ...................... ESC-TAB   Complete filename & reverse cycle.
 ctrl-L ................................... Complete filename, list all.

 ---------------------------------------------------------------------------

1.1.3 git命令关键字

项目内执行过的git命令是没法查看的,不存在git history命令

start a working area (see also: git help tutorial)
   clone     Clone a repository into a new directory
   init      Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add       Add file contents to the index
   mv        Move or rename a file, a directory, or a symlink
   restore   Restore working tree files
   rm        Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect    Use binary search to find the commit that introduced a bug
   diff      Show changes between commits, commit and working tree, etc
   grep      Print lines matching a pattern
   log       Show commit logs
   show      Show various types of objects
   status    Show the working tree status

grow, mark and tweak your common history
   branch    List, create, or delete branches
   commit    Record changes to the repository
   merge     Join two or more development histories together
   rebase    Reapply commits on top of another base tip
   reset     Reset current HEAD to the specified state
   switch    Switch branches
   tag       Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch     Download objects and refs from another repository
   pull      Fetch from and integrate with another repository or a local branch
   push      Update remote refs along with associated objects

1.1.4 git名词介绍

【git】git基础总结与SourceTree的使用和配置_第3张图片

【git】git基础总结与SourceTree的使用和配置_第4张图片

只有推送push会影响远端分支,其他所有操作都是影响当前分支head,不会影响别的分支

克隆/新建(clone):从远端仓库URL加载创建一个与远端仓库一样的本地版本库。
提交(commit):将暂存区文件上传到本地代码仓库(提交的是对文件的修改操作,而不是当前工作区的文件)
推送(push):将本地版本库同步至远端仓库,一般推送(push)前先拉取(pull)一次,确保一致(十分注意:这样你才能达到和别人最新代码同步的状态,同时也能够规避很多不必要的问题)。
拉取(pull):从远端仓库获取信息并同步至本地版本库,并且自动执行合并(merge)操作(默认git pull=git fetch+git merge)。
获取(fetch):从远端仓库获取信息并同步至本地版本库。
分支(branch):创建/修改/删除分枝。
合并(merge):将多个同名文件合并为一个文件,该文件包含多个同名文件的所有内容,相同内容抵消。
贮藏(git stash):保存工作现场。
丢弃(Discard):丢弃更改,恢复文件改动/重置所有改动,即将已暂存的文件丢回未暂存的文件。
标签(tag):给项目增添标签。
工作流(Git Flow):团队工作时,每个人创建属于自己的分枝(branch),确定无误后提交到master分支。
终端(terminal):可以输入git命令行。
每次拉取和推送的时候不用每次输入密码的命令行:git config credential.helper osxkeychain sourcetree。
检出(checkout):切换不同分支。
添加(add):添加文件到缓存区。
移除(remove):移除文件至缓存区。
重置(reset):回到最近添加(add)/提交(commit)状态。

【git】git基础总结与SourceTree的使用和配置_第5张图片

1.2 暂存区

暂存区存储的是要提交的文件,可以通过ls-files查看暂存区内的文件

1.2.1 #init 创建本地版本库

【git】git基础总结与SourceTree的使用和配置_第6张图片

1.2.2 #status 比较工作区和暂存区的差异

查看工作区内可以放入暂存区的内容

git status #会显示所有可以放入暂存区的内容(暂存区的内容记录在ls-files内)
git status -s #更直观的查看暂存区状态
# ?表示未跟踪,M表示已修改modified,A表示当前添加到了暂存区
# 红色:不在暂存区ls-files
# 绿色:在暂存区

【git】git基础总结与SourceTree的使用和配置_第7张图片

【git】git基础总结与SourceTree的使用和配置_第8张图片

【git】git基础总结与SourceTree的使用和配置_第9张图片

1.2.2.1 解决status中文乱码问题

【git】git基础总结与SourceTree的使用和配置_第10张图片

git config --global core.quotepath false

【git】git基础总结与SourceTree的使用和配置_第11张图片

1.2.3 #add 提交文件到暂存区

提交commit、暂存add的都是对文件的修改操作,而不是本地的文件

放入暂存区内的文件,才是被跟踪的文件,文件被提交后,会记录在ls-files内,如果文件在暂存区列表ls-files中被删掉rm,则文件又会变为未被跟踪untracked状态,未被跟踪相当于新文件

git status  # 查看工作区内可以提交到暂存区的文件

git add .  #把所有修改操作都放入暂存区ls-files  #把git status内可以放入的文件都放入暂存区

git add ggg/ppp/ttt.txt #添加指定文件的修改操作放入暂存区

#重置为未跟踪状态,不进行git管理,但保留工作区文件
git rm --cached ggg/ppp/ttt.txt
  • add的逆操作
git restore --staged ggg/ppp/ttt.txt #从暂存区内移除修改操作,工作区内保留 #是add的逆操作

【git】git基础总结与SourceTree的使用和配置_第12张图片

【git】git基础总结与SourceTree的使用和配置_第13张图片

1.2.4 查看暂存区的内容 #ls-files

暂存区文件列表ls-files,记录了所有被跟踪的文件,即所有被git管理的文件,在ls-files的文件,之后会被推送到远端仓库

未跟踪的文件,通过add保存到暂存区,此时被git管理,记录在ls-files

通过删除rm --cachedrm可以删除ls-files内的文件,让文件不被git管理,文件会变成未跟踪状态untracked,不会被推送到远端仓库

git ls-files #查看当前暂存区的文件列表(之后会被提交为新版本)
git ls-files|grep xxx  #在暂存区内查找指定文件

1.2.4.1 删除暂存区内的文件,删除远端分支的文件 #rm #cached

rm 文件 # 只操作工作区

git rm 文件相对路径  #同时操作暂存区和工作区

git rm --cached 文件相对路径 #只操作暂存区,删除暂存区ls-files的文件,让其变为未跟踪状态
#删完暂存区的文件,再push就能删除远端的文件了
git rm -rf --cached ggg/  # 递归删除目录
  • 如果要删除当前版本的文件

    • 不管理这个文件,但工作区保留:只需要rm --cached即可,文件变为untracked状态
    • 不管理这个文件,同时工作区删除这个文件:使用rm即可
  • 如果工作区的文件有修改,但未暂存该版本,此时,需要强制删除git rm -f

  • 如果要递归删除目录内的所有内容,此时需要用到git rm -r,递归强制删除git rm -rf

【git】git基础总结与SourceTree的使用和配置_第14张图片

1.2.5 移动、重命名已跟踪的文件 #mv

如果a.txt已跟踪(在暂存区内ls-files),a.txt现在要重命名为b.txt

git mv a.txt b.txt #会在暂存区、工作区同时修改文件名 #移动文件或重命名文件
git mv amssji.txt ggg/amppp.txt

等价于

mv a.txt b.txt #重命名或移动文件a到b
git rm --cached a.txt # 只在暂存区删除旧文件a
git add b.txt  #新文件名b
  • 如果使用sourcetree,重命名文件后,可以直接自动生成对应的rmadd命令,暂存后直接提交即可

【git】git基础总结与SourceTree的使用和配置_第15张图片

1.3 本地版本库

1.3.1 #commit 提交文件修改操作到本地版本库

提交commit、暂存add的都是对文件的修改操作,而不是本地的文件
只有被git管理(跟踪)的文件才会被提交到远端仓库和版本库

git commit -m 'xxxx'  # -m 直接写提交注释

【git】git基础总结与SourceTree的使用和配置_第16张图片

1.3.1.1 git commit -m和git commit -am的区别

只要文件已经在暂存区内ls-files(已跟踪),修改文件后,就可以用commit -am直接提交文件,跳过add操作

【git】git基础总结与SourceTree的使用和配置_第17张图片

【git】git基础总结与SourceTree的使用和配置_第18张图片

1.3.1.2 提交无改动版本

git commit -m '新版本开始' --allow-empty

【git】git基础总结与SourceTree的使用和配置_第19张图片

1.3.2 #log 查看所有分支的提交日志

git log --oneline #查看当前分支日志
git log --oneline --graph --all #查看所有分支,包括远端分支日志

git log -3  #查看最近的3条日志
git log --oneline --graph -3

git log --stat -2 #查看版本对应修改的文件列表

git log --oneline --stat --all --graph -5

【git】git基础总结与SourceTree的使用和配置_第20张图片

【git】git基础总结与SourceTree的使用和配置_第21张图片

【git】git基础总结与SourceTree的使用和配置_第22张图片

1.3.3 #show 比较当前和上一次提交的内容

当前内容是+++,即最新内容

【git】git基础总结与SourceTree的使用和配置_第23张图片

【git】git基础总结与SourceTree的使用和配置_第24张图片

1.3.3.1 例子

【git】git基础总结与SourceTree的使用和配置_第25张图片

【git】git基础总结与SourceTree的使用和配置_第26张图片

【git】git基础总结与SourceTree的使用和配置_第27张图片

【git】git基础总结与SourceTree的使用和配置_第28张图片

1.3.4 #gitignore 让文件不被跟踪

git不会检查gitignore规则匹配的指定文件,不会提示要跟踪这些文件,这些文件始终保持untraced未跟踪状态

【git】git基础总结与SourceTree的使用和配置_第29张图片

1.3.4.1 glob 模式匹配规则

glob模式是shell简化了的正则表达式

【git】git基础总结与SourceTree的使用和配置_第30张图片

例子:
【git】git基础总结与SourceTree的使用和配置_第31张图片

1.3.5 #reset 回滚到任意指定版本

reset可以回滚到任意分支的任意指定版本(不单只是当前结点的历史版本)
reset不会产生冲突

  • reset的三种方式:
#工作区不变
git reset --soft 版本号  #软合并,工作区不变,到指定版本的修改操作被保存到了暂存区
git reset --mixed 版本号 #混合合并,工作区不变,到指定版本的修改操作被记录,但没放到暂存区

#重置工作区
git reset --hard 版本号 #硬合并,工作区变成指定版本的状态,丢弃修改操作

1.3.5.1 硬合并,重置工作区 #hard

硬合并,工作区变成指定版本的状态,丢弃修改操作

git reset --hard 版本号 #硬合并,丢弃修改操作

【git】git基础总结与SourceTree的使用和配置_第32张图片

1.3.5.2 混合合并,工作区不变 #mixed

混合合并,工作区不变,到指定版本的修改操作被记录,但没放到暂存区
如果丢弃修改操作,就等价于--hard

git reset --mixed 版本号 #混合合并,修改操作回到工作区

【git】git基础总结与SourceTree的使用和配置_第33张图片

1.3.5.3 软合并,工作区不变 #sort

git reset默认使用软合并

软合并,工作区不变,到指定版本的修改操作被保存到了暂存区
如果丢弃修改操作,就等价于--hard

git reset --soft 版本号  #软合并,修改操作回到暂存区

【git】git基础总结与SourceTree的使用和配置_第34张图片

1.3.6 #reflog 查看head指针的移动轨迹,查看历史版本号

log是查看所有版本历史commit id
refloghead指针的移动日志,即head指针的commit id移动路径

  • reflog不会记录push操作,因为push操作不会使得head指针发生移动,因此无法回滚push操作
git reflog -3  #查看最近的3条head指针移动日志

【git】git基础总结与SourceTree的使用和配置_第35张图片

  • 使用reset进行commit版本回滚
    注意:只要是影响本地的操作,都可以回滚,如add, pull, rm,但影响远端仓库的操作push无法回滚

【git】git基础总结与SourceTree的使用和配置_第36张图片

使用log无法查看回滚后的版本记录commit id(但是可以通过reflog查看到所有历史版本记录commit id

使用reflog查看head指针的历史移动轨迹,有对应的历史commit id,可以通过这些历史commit id,通过reset+branch找回分支的历史版本

【git】git基础总结与SourceTree的使用和配置_第37张图片

【git】git基础总结与SourceTree的使用和配置_第38张图片

1.3.7 更新本地代码 #pull #fetch

git pull origin test #拉取远端origin/test到当前本地分支

git pull --set-upstream origin test #拉取远端origin/test到本地仓库,并设置跟踪关系,可以使用origin简写

建议先fetch获取远端仓库的log日志(不会改动当前版本head

git fetch 就是把远端仓库的日志log拉取下来,不会改变工作区,不会改变当前版本head

git pull 会更新工作区的代码,默认是fetch+merge操作,有合并冲突就必须手动处理冲突,合并后,当前版本head移动到合并后的新节点位置

【git】git基础总结与SourceTree的使用和配置_第39张图片

【git】git基础总结与SourceTree的使用和配置_第40张图片

默认更新方式:git merge origin/master,把分叉点后origin/master的修改操作以新结点方式追加到当前分支后

【git】git基础总结与SourceTree的使用和配置_第41张图片

1.3.7.1 例子:fetch+merge更新代码,pull的默认更新方式

【git】git基础总结与SourceTree的使用和配置_第42张图片

1.3.7.2 pull使用rebase方式更新代码,推荐 #rebase

git pull --rebase origin  #推荐拉取方式 

【git】git基础总结与SourceTree的使用和配置_第43张图片

【git】git基础总结与SourceTree的使用和配置_第44张图片

1.3.8 贮藏已跟踪文件的修改操作 #stash

可以把当前版本所有已跟踪但未提交的修改操作都贮藏起来,重置工作区的所有已跟踪文件为未修改状态

git stash	#存储工作区内已跟踪文件的修改操作
git stash save 'development' 	#存储工作区并添加备注内容
git stash list 		#查看已贮藏区列表
git stash apply stash@{1}		#应用最新git贮藏的内容(应用后不删除该贮藏)
git stash pop stash@{1} 		#应用最新贮藏的内容(应用后该贮藏的内容会被删除!)
git stash drop stash@{1} 		#删除最新贮藏的内容
git stash show stash@{1} 		#查看指定贮藏内容用于当前工作区后的效果
git stash clear #删除所有贮藏内容

【git】git基础总结与SourceTree的使用和配置_第45张图片

1.4 远端仓库

【git】git基础总结与SourceTree的使用和配置_第46张图片

1.4.1 远端仓库配置ssh公钥,推荐ssh拉取代码

1.4.1.1 生成ssh公钥 #ssh-keygen

git config --global -l
ssh-keygen -t rsa -C "[email protected]"
cat ~/.ssh/id_rsa.pub #这也是默认的ssh公钥文件位置

【git】git基础总结与SourceTree的使用和配置_第47张图片

默认的ssh公钥文件位置:

【git】git基础总结与SourceTree的使用和配置_第48张图片

1.4.1.2 github添加生成的ssh公钥

gitee, gitea等添加本地生成的ssh公钥类似

【git】git基础总结与SourceTree的使用和配置_第49张图片

【git】git基础总结与SourceTree的使用和配置_第50张图片

1.4.2 克隆远端仓库到本地版本库 #clone

可以克隆远端分支到任意指定目录下

如果是ssh方式克隆,需要在远端仓库配置本地生成的ssh公钥 (用git工具还需要把ssh公钥配置到git工具内)
如果是http方式克隆,则直接克隆即可

克隆后,可以通过config配置项目专有的开发者身份标识,可以使用config --local查看开发者身份标识

【git】git基础总结与SourceTree的使用和配置_第51张图片
【git】git基础总结与SourceTree的使用和配置_第52张图片

1.4.3 例子:推送本地项目到远端仓库

  • 首先,在github创建空的远端仓库

【git】git基础总结与SourceTree的使用和配置_第53张图片

本地默认的ssh公钥路径为`~/.ssh/id_rsa.pub

然后根据本地的情况选择对应的代码同步方案:

  • 如果本地没有代码
    直接克隆远端项目,拉代码进行开发
git clone 远端仓库链接 # 在当前项目内创建项目目录
  • 如果本地已经有项目代码
    在项目目录中设置远端仓库地址origin,进行开发
git init  # 使用git管理本地项目
git remote add origin 远端仓库链接 #设置远端仓库地址

或者先克隆远端项目clone,再把已有代码粘贴过去

最后,要推送的代码放到暂存区add,再推送代码git push origin即可
如果是fork别人的远端仓库,push到远端后,再创建合并请求pull request即可

1.4.4 #config 项目git配置信息

1.4.4.1 标记提交代码的开发者身份

设定用户和邮箱来区别不同的开发者

【git】git基础总结与SourceTree的使用和配置_第54张图片

1.4.4.2 全局配置 #global

git config --global -l #查看配置
git config --global user.name "xxx" #设置提交用户名标识
git config --global user.email "[email protected]" #设置提交用户的邮箱标识
git config -list

【git】git基础总结与SourceTree的使用和配置_第55张图片

1.4.4.3 局部配置,设置仓库的开发者身份 #local

git config --local -l #查看配置
git config user.name xxxx
git config user.email [email protected]
cat .git/config

【git】git基础总结与SourceTree的使用和配置_第56张图片

【git】git基础总结与SourceTree的使用和配置_第57张图片

1.4.4.4 编辑器修改配置

git config -e #修改本地项目配置 #等价于 git config --local -e
git config --global -e #修改全局项目配置

【git】git基础总结与SourceTree的使用和配置_第58张图片

1.4.5 #origin 远端仓库地址

可以使用config -e设置远端仓库地址

【git】git基础总结与SourceTree的使用和配置_第59张图片

1.4.5.1 远端仓库地址 #remote

【git】git基础总结与SourceTree的使用和配置_第60张图片

1.4.5.2 设置本地分支的跟踪关系,使用origin简写

克隆项目后,配置内本地master分支跟踪的是远端的origin/master分支

【git】git基础总结与SourceTree的使用和配置_第61张图片

【git】git基础总结与SourceTree的使用和配置_第62张图片

【git】git基础总结与SourceTree的使用和配置_第63张图片

  • 如果没有跟踪关系,可以在push或pull的时候,顺便设置跟踪关系
    注意:必须是跟踪同名的远端分支,否则无法push origin简写,只能pull origin简写
git push -u origin test #推送到远端origin/test,并设置跟踪关系,即origin等价于origin test:test
#等价于
git push --set-upstream origin test

git pull --set-upstream origin test #拉取远端origin/test到本地分支ppp,并设置跟踪关系

  • checkout切换本地分支时,会显示对应跟踪的远端分支
    【git】git基础总结与SourceTree的使用和配置_第64张图片

  • sourcetree跟踪远端分支
    【git】git基础总结与SourceTree的使用和配置_第65张图片

1.4.6 #push 把本地分支内容推送到指定的远端分支

git push origin master:dev #本地分支master到远端origin/dev #写全要推送的远端分支 #如果远端没有该分支,就创建分支

git push origin 
# 如果有跟踪关系,则可以使用origin简写
# 如果没有跟踪,则需要配置跟踪关系,否则必须写全远端分支

git push -u origin test #推送到远端origin/test,并设置跟踪关系,之后可以使用origin简写 #必须推送到已有分支
#等价于
git push --set-upstream origin test

【git】git基础总结与SourceTree的使用和配置_第66张图片

可以修改config来修改远端分支跟踪关系test.merge和远端仓库地址origin.url

git config -e # 修改本地项目配置

1.4.6.1 例子

【git】git基础总结与SourceTree的使用和配置_第67张图片

1.4.6.2 推送代码前,必须先更新代码 #pull

【git】git基础总结与SourceTree的使用和配置_第68张图片

【git】git基础总结与SourceTree的使用和配置_第69张图片

1.4.6.3 强制推送,强制覆盖远端分支

注意:对远端仓库的推送操作push,无法通过reflog回滚

git push -f origin # -f 等价于 --force

1.4.6.4 回滚远端分支的版本

对远端分支的所有操作,都是先在本地操作后,再推送push到远端仓库来实现的

1.4.6.4.1 方式一:推送修改操作,回滚远端分支,推荐 #soft #reset

这种是安全的回滚方式

git checkout -b merge 62bc
git reset --soft 20b2
git commit -am '回退到旧版本'
git push origin merge:dev

【git】git基础总结与SourceTree的使用和配置_第70张图片

1.4.6.4.2 方式二:强制推送覆盖远端分支,不推荐

不安全的回滚远端分支方式

强制推送,让本地分支强制覆盖远端分支,日志和内容都会被覆盖
不要随意用这种方式修改远端分支的提交历史,因为别人也在使用拉取的远端历史记录

操作不可逆,push --force会修改日志reflog
强制推送可以用于修改日志的路线

先回滚本地分支reset,再通过push --force origin强制覆盖远端分支,实现远端分支的版本回滚

git checkout -b merge
git reset --hard 0b24
git push --force origin merge:dev

【git】git基础总结与SourceTree的使用和配置_第71张图片

1.4.7 发起合并请求 pull request #PR

  • 对于自己的仓库来说:合并请求是合并两个指定的远端分支
  • 对于别人的仓库来说:合并请求是请求别人远端仓库的指定远端分支合并自己远端仓库的指定远端分支

【git】git基础总结与SourceTree的使用和配置_第72张图片

1.4.7.1 例子:合并自己的远端分支

【git】git基础总结与SourceTree的使用和配置_第73张图片

1.4.7.1.1 处理合并请求 #rebase #merge
  • 处理合并请求的两种方式:rebasemerge
    • 默认处理方式:merge
    • 不管是哪一种方式,都是把origin/test的操作放到origin/master的末尾

【git】git基础总结与SourceTree的使用和配置_第74张图片

  • merge方式合并(默认方式)
    【git】git基础总结与SourceTree的使用和配置_第75张图片

  • rebase方式合并

【git】git基础总结与SourceTree的使用和配置_第76张图片

1.4.7.2 例子:请求别人的远端分支合并自己的远端分支 #fork

在别人的仓库发起合并请求

1.4.7.3 回滚指定pr的修改操作 #revert

【git】git基础总结与SourceTree的使用和配置_第77张图片

1.4.8 删除远端分支

注意:删除远端分支不可逆,无法恢复

git push --delete origin dev  #删除远端'origin/dev'分支

1.5 本地分支管理

1.5.1 #branch 查看分支,生成本地分支的快照

git branch # 查看本地分支名称

git branch -a # 查看本地和远端分支名
git branch -av # 查看本地和远端分支名+当前版本号origin/head+注释

【git】git基础总结与SourceTree的使用和配置_第78张图片

branch的用法:

  • 查看当前分支(星号*表示)
  • 查看已有分支
  • 生成当前本地分支的快照

【git】git基础总结与SourceTree的使用和配置_第79张图片

1.5.1.1 创建新分支

在当前分支节点head基础上,创建新分支(生成当前结点head的快照)

【git】git基础总结与SourceTree的使用和配置_第80张图片

【git】git基础总结与SourceTree的使用和配置_第81张图片

  • 创建dev分支并跟踪指定远端origin/test分支
    • 默认创建分支后,没有跟踪任何远端分支,即分支无法使用origin进行任何操作,必须写全远端分支,如git push origin ppp:ppp
    • 如果指定了跟踪关系,则分支和远端分支同步,和当前分支无关
    • 没有指定跟踪关系,则默认在当前分支的基础上创建
git branch dev origin/dev # 创建dev分支,dev跟踪origin/dev
git branch dev # 创建dev分支,默认dev没有跟踪任何远端分支,即分支dev无法使用origin

1.5.1.2 强制删除指定分支 -D

  • 无法在当前分支删除当前分支
git branch -D dev  #强制删除'dev'分支

【git】git基础总结与SourceTree的使用和配置_第82张图片

1.5.1.3 恢复被删掉的本地分支

【git】git基础总结与SourceTree的使用和配置_第83张图片

1.5.2 #checkout 检出到指定分支

一旦checkout到指定分支上,则在该分支上进行的任何操作,只会影响自己,不会影响别的分支(变的只是当前所在的分支,别的分支不变)

checkout的两种用法:

  • 切换到指定本地分支checkout
  • 创建新分支,默认在当前分支基础上创建checkout -b
    • 如果checkout -b指定了跟踪关系,则分支和远端分支同步,和当前分支无关

【git】git基础总结与SourceTree的使用和配置_第84张图片

1.5.2.1 在指定版本创建分支并切换

可以检出远端分支内容,但创建分支后,无跟踪远端分支,需要写全远端分支

git checkout -b tb origin/dev a485

【git】git基础总结与SourceTree的使用和配置_第85张图片

1.5.2.2 创建并签出到分支,并指定跟踪关系

创建后的分支和跟踪的分支同步,而不是在当前分支的接触上创建分支

git checkout -b tt origin/test

【git】git基础总结与SourceTree的使用和配置_第86张图片

1.5.2.3 通过贮藏处理签出冲突 #stash

如果checkout发生冲突,说明工作区或暂存区有文件内容冲突

git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks checkout poster --progress
error: The following untracked working tree files would be overwritten by checkout:
	README.md
Please move or remove them before you switch branches.
Aborting

【git】git基础总结与SourceTree的使用和配置_第87张图片

【git】git基础总结与SourceTree的使用和配置_第88张图片

1.5.2.4 签出远端分支

#查看远端分支
git branch -r 

#签出远端分支warning_test到本地分支test上
git checkout -b test origin/warning_test

1.5.3 #merge 合并分支,生成新结点

合并后git merge,会留下合并的痕迹,即使合并的分支被删掉,合并的痕迹一定会保留下来
合并后,不想留合并痕迹可以使用git merge --squash

【git】git基础总结与SourceTree的使用和配置_第89张图片

1.5.3.1 例子:无分叉merge,快速移动 #Fast-forward

【git】git基础总结与SourceTree的使用和配置_第90张图片

【git】git基础总结与SourceTree的使用和配置_第91张图片

1.5.3.2 例子:有分叉merge(理解merge操作)

必须确保future操作不能在master分支操作前面,因此只能追加到末尾

  • 注意:mastergit merge future,和futuregit merge master的结果结点顺序不同,正确顺序是mastergit merge future

【git】git基础总结与SourceTree的使用和配置_第92张图片

1.5.3.2.1 对比mergerebase #rebase

如果在 master 分支上,则使用 merge 整合到 master 分支
如果在 future 分支上,则使用 rebase 整合到 master

master分支上,不能去rebase其他分支,否则会导致操作顺序问题,即要保证新功能是后追加的

【git】git基础总结与SourceTree的使用和配置_第93张图片

  • merge后会留下合并的轨迹,可以看出是哪些分支参与了开发
  • rebase后,看起来好像始终只有一个分支在开发,不会留下rebase的痕迹

【git】git基础总结与SourceTree的使用和配置_第94张图片

  • 如果不让merge留下痕迹,可以使用git merge --squash

【git】git基础总结与SourceTree的使用和配置_第95张图片

1.5.3.3 例子:手动处理合并冲突 #冲突

冲突只能通过手动处理,在有冲突的区域,编写最终版本
最终版本写什么都行,只要把<<>>>test去掉就表示冲突已解决

【git】git基础总结与SourceTree的使用和配置_第96张图片

1.5.3.4 放弃合并

【git】git基础总结与SourceTree的使用和配置_第97张图片

1.5.4 #diff 比较文件内容差异

比较的都是已跟踪文件(被git管理的文件)

【git】git基础总结与SourceTree的使用和配置_第98张图片

【git】git基础总结与SourceTree的使用和配置_第99张图片

1.5.4.1 例子:比较工作区和暂存区ls-files

就是比较工作区和暂存区ls-files的文件内容差异
ls-files的文件列表可以理解为待提交的内容,提交了就是下一版本

  • 如果只是查看有差异的文件列表,可以使用git status,使用git diff可以详细查看哪些文件内容有差异

【git】git基础总结与SourceTree的使用和配置_第100张图片

【git】git基础总结与SourceTree的使用和配置_第101张图片

1.5.4.2 例子:比较工作区和指定版本

【git】git基础总结与SourceTree的使用和配置_第102张图片

1.5.4.3 例子:比较暂存区ls-files和指定版本 #cached #staged

【git】git基础总结与SourceTree的使用和配置_第103张图片

【git】git基础总结与SourceTree的使用和配置_第104张图片

1.5.4.4 例子:比较不同版本

比较不同commit id的区别

【git】git基础总结与SourceTree的使用和配置_第105张图片

【git】git基础总结与SourceTree的使用和配置_第106张图片

1.5.5 丢弃文件的修改操作 #restore #stash

stash可以一次性放弃所有文件的修改操作,且可以恢复修改操作
restore每次只能放弃对一个文件的修改操作,但无法恢复修改操作

git restore --staged 文件路径 #暂存区丢弃对文件的修改,工作区保留修改,是add的逆操作 
git restore 文件路径 # 工作区丢弃对文件的修改(修改操作丢失)

git stash #贮藏所有修改操作

【git】git基础总结与SourceTree的使用和配置_第107张图片

【git】git基础总结与SourceTree的使用和配置_第108张图片

1.5.6 #rebase #变基 指定修改起点,迁移所有修改操作到指定分支

rebase变基即把当前分支的基点(分叉点)后所有操作,迁移到指定分支的末尾进行,不会生成新结点

必须确保master分支操作在future分支操作前面,因此只能迁移future分支操作到master分支操作末尾

rebase对指定的分支无影响,对当前分支有影响

如果变基过程中发生冲突,则解决冲突后,继续变基,直到变基完成

【git】git基础总结与SourceTree的使用和配置_第109张图片

1.5.6.1 例子

【git】git基础总结与SourceTree的使用和配置_第110张图片

【git】git基础总结与SourceTree的使用和配置_第111张图片

1.5.6.2 例子:没有使用rebase

【git】git基础总结与SourceTree的使用和配置_第112张图片

1.5.6.3 例子:使用rebase,指定修改起点

【git】git基础总结与SourceTree的使用和配置_第113张图片

1.5.7 #cherry-pick #优选 复用其他分支的提交内容

【git】git基础总结与SourceTree的使用和配置_第114张图片

【git】git基础总结与SourceTree的使用和配置_第115张图片

2 SourceTree使用git

2.1 配置

2.1.1 添加ssh公钥

添加.pub.ppk
【git】git基础总结与SourceTree的使用和配置_第116张图片

2.1.2 设置默认克隆项目位置

【git】git基础总结与SourceTree的使用和配置_第117张图片

2.2 克隆项目 #clone

如果使用ssh协议连接远端仓库,则需要先在sourceTree和远端仓库中配置ssh公钥public key

【git】git基础总结与SourceTree的使用和配置_第118张图片

2.3 添加到暂存区 #add

【git】git基础总结与SourceTree的使用和配置_第119张图片

2.4 推送到本地版本库 #commit

【git】git基础总结与SourceTree的使用和配置_第120张图片

2.5 更新代码 #pull

2.5.1 merge方式更新代码

git merge origin/master,修改操作追加到当前分支末尾,本地修改可能被覆盖

【git】git基础总结与SourceTree的使用和配置_第121张图片

2.5.2 rebase方式更新代码

git rebase origin/master,本地操作不会被覆盖

2.6 推送本地分支到远端分支 #pull #push

先rebase更新本地版本库,再推送到远端分支(推荐)

【git】git基础总结与SourceTree的使用和配置_第122张图片

【git】git基础总结与SourceTree的使用和配置_第123张图片

2.7 切换本地分支,拉取远端分支 #checkout

对于本地分支,检出checkout就是切换当前本地分支(双击切换)
对于远端分支,检出checkout就是把远端的指定分支克隆到本地版本库(右键checkout

  • 对于本地分支:
    【git】git基础总结与SourceTree的使用和配置_第124张图片

  • 对于远端分支:

对应指令

git checkout -b tt origin/develop

【git】git基础总结与SourceTree的使用和配置_第125张图片

2.8 新建分支 #checkout #branch

新建分支,即克隆当前分支

【git】git基础总结与SourceTree的使用和配置_第126张图片

【git】git基础总结与SourceTree的使用和配置_第127张图片

2.9 合并分支 #merge

合并分支,不会影响别的分支内容,只会改变当前分支

【git】git基础总结与SourceTree的使用和配置_第128张图片

2.9.1 例子:手动解决冲突

冲突只能手动解决,对有冲突的区域,选择最终要保留的代码

在工作区内,有冲突的文件会处于未暂存状态,对文件内的冲突代码进行修改,确定最终版本

【git】git基础总结与SourceTree的使用和配置_第129张图片

【git】git基础总结与SourceTree的使用和配置_第130张图片

2.9.2 冲突比较工具:BeyondCompare

2.9.2.1 配置

【git】git基础总结与SourceTree的使用和配置_第131张图片

2.9.2.2 例子

【git】git基础总结与SourceTree的使用和配置_第132张图片

2.10 贮藏已跟踪文件的修改操作 #stash

【git】git基础总结与SourceTree的使用和配置_第133张图片

【git】git基础总结与SourceTree的使用和配置_第134张图片

2.11 变基 #rebase

【git】git基础总结与SourceTree的使用和配置_第135张图片

2.12 在日志中查找指定版本

2.12.1 例子:查找某个人的提交记录

+【git】git基础总结与SourceTree的使用和配置_第136张图片

2.13 回滚工作区到指定版本 #reset

【git】git基础总结与SourceTree的使用和配置_第137张图片

你可能感兴趣的:(Git,git,bash,linux)