zoukankan      html  css  js  c++  java
  • 再谈git和github-深入理解

    git中的 objects 和 refs 是什么?

    目录objects是仓库的 "对象库" , 是包含 代码, 提交, 日志, 信息, 索引等信息的关键所在
    refs是一些 sha1 命名的文件, 里面是各种引用, 是对 各个分支 的最新节点 指针, 各次提交 的引用

    如何理解 HEAD?

    HEAD指明了, 你当前正在 工作的 所在分支的最新节点 位置.

    如何理解git github的工作过程? 参考: https://www.zhihu.com/question/20070065

    什么是index呢?

    是git的暂存区 stage. 是一个中转点, 中转地点, 中转仓库, 是 工作区 和 本地仓库 之间的 桥梁. 目的是做一些 中间的 处理工作, 比如 对工作区 提交到仓库的 修改做一个 登记, 记录, 便于后面的操作; 便于 工作区修改的 撤销: 即我突然又不想将某个修改提交到仓库了, 这样可以直接从 index索引区撤销, 可以提高操作的效率.

    为什么git能够回滚到历史记录呢?

    • 是因为每一次提交 commit, 就相当于 做了依次 项目/工程的 备份点一样( 备份节点), 每次 提交时 都会生成一个 唯一的 commit id, 一个 hash值
    • 所以如同windows 的系统备份点一样, 可以保存多个备份点, 然后你可以选择 随时恢复到 / 回滚到 某个备份点. git的rollback 采用了同样类似的 操作.

    linux进程的创建有 : fork(), vfork(), clone() , 跟它们比较近似的一个概念是 复制 copy: 基本上 它们都要涉及到一个类似的过程, 即复制. copy-on-write

    关于git github上的 "推拉" 的理解 参考: https://www.zhihu.com/question/21682976

    push是推
    pull是: 拉, 除了 "拉"之外, 还有: 牵, 拽, 扯, 拔, 拖等动作的意思.

    在git中 你要修改别人的东西,(不可能允许你直接修改) 需要走的流程是:

    • 不能直接在别人的 主线(master branch 分支) 上直接修改;
    • 先fork一份副本 , 然后修改/增删 git commit, 然后把你的这些工作 git pull(requests)请求, 以等待 原作者(主线, 主版本的作者)是否接收采纳, 最后如果原作者 采纳了, 就git merge 把你的工作 "合并" 进去.
    #### 确实, 你的行为是push 推送到 原仓库 上去, 但是, 别人要不要采纳你的代码, 决定权在 原作者手里, 所以, 你是要 向原作者 发出一个 "requests"请求, 让原作者 把你的 fixing "拉到 " 他的 master branch 分支上去. 所以 要发起的是 pull requests, 你看那个 图标就知道了.
    • 但是好像 用户 也可以 从 远程仓库:github上 将仓库的 最新更改 --> pull 到 本地机器上的 working space??

    git 的checkout操作?

    • checkout n. 两个意思: 1. 检验,校验; 2. 结帐;
      The idea must undergo the checkout of experiment. 观念必须经得起实验的 检验。
      At the supermarket, Candida chose the shortest checkout line. 在超级市场里, 坎迪德选一条最短的 结账 队来排.
      You may take that to the checkout counter, madam, and good luck to ya. 你现在可以去收款处了, 女士, 祝你好运.

    • git checkout -b newbranch [<start_point>]
      这样用可以创建新的分支并切换到新分支上去,b代表branch的意思,newbranch 是新分支的名称,如果没有指定提交点(start_point),默认从HEAD指向的提交创建分支。

    • git branch [<start_point>]
      创建新的分支,但是不会切换到新建的分支上,如果没有指定start_point,默认从HEAD指向的提交创建分支

    fork和编辑git的过程 参考: http://www.cnblogs.com/hutaoer/archive/2013/05/07/git_checkout.html

    • fork是从别人的项目仓库中, 复制一份到你的 github账号仓库中
    • 但是你要 用 git clone 从 github的网上仓库中 下载到你的本地机器上, 才好编辑. 所以本地机器上也有一份仓库, 本地机器也是服务器, 就是分布式版本库的含义
    • .git/HEAD 是git分支的精髓和关键. 它是一个引用(类似ln链接文件) 目标是: .git/refs/heads/master 文件: 在多个引用refs的 多种头部指针heads/ 的master (即HEAD指向的是master, 然后master 指向的是 最新一次的提交.)
      但是 分支通常不只是一个, 可以有多个分支, 因此 .git/refs/heads/ 下就有多个分支的head. 名称就是 分支的名称, 比如: master分支是: refs/heads/master, foo分支是 refs/heads/foo

    参考: https://segmentfault.com/a/1190000002783245

    这个操作主要会用到两个命令: branch和checkout命令.
    创建新分支:git branch branchName
    切换到新分支:git checkout branchName
    然后,上面两个命令也可以合成为一个命令: (这里的 -b 是 branch的意思)
    git checkout -b branchName
    

    linux中的printf命令?

    • 只有/usr/bin/printf命令, 没有print命令
    • 格式输出时, %s是按字符串输出, %c是输出字符串的第一个字符, 如果是数字型格式, 比如 整数%d=%i, %e %f则要求后面的字符串是 数字形式的字符串,否则会报错 : invalid number
    • 后面的参数都默认的 认为 是字符串, 不管你加不加 引号

    linux中的sha1sum命令
    这个是计算 文件/字符串的 sha1 哈希值的命令

    • 可以是文件, 如果没有指定文件, 则从stdin读取 用 "-" 表示?
    • checksums是什么意思? "校验和" 是 sha1 的另一个特征?
    • sha1 就是哈希值. 表示符号不是hash, 本身就有一个1
    • 哈希值共 160bit, 20个字节, 是不是表示 应该用 20个数字/字符来表示呢? 实际上, sha1是用40个16进制的 数字来表示的: 因为一个16进制 的数字, 本身并不表示一个字符/1个字节(它只占4个bit) , 而是两个16进制数字表示一个字节. 所以共有 160/4=40个16机制数

    git中的cat-file命令?

    • 是指 provide content or type and size information for git repository **objects ** 是为了显示 仓库对象的 内容或类型/大小信息. 因为 对象本身是不可以直接读的, 即不能直接 cat a_git_repos_object, 所以 要用cat-file 即显示/打印 对象中的 文件 这个命令
    • 命令的参数有: -t 显示对象的类型, -s对象的大小 -p 这个正是显示对象所包含的文件的内容.(比如 commit对象中 所包含的 提交文件的 "文本内容")

    github上的仓库 默认名称: "用户名.github.io" 仓库名是用点号连接的,不是用-连接
    git clone的地址, 应该在仓库名的后面 加一个 .git, 虽然不加的时候也能clone
    re'pository 重音在re后面, checking connectivity...

    代码风格中的标点符号前后的空格?

    • 英语中的标点符号 (包括:,"; ... 省略号 等) 前面来说, 总是紧跟着前面那个单词, 但是标点符号的后面要 留一个空格, 因为西文是用 空格来分词的, 所以 写作和 代码中的空格 非常重要
    • 只有一些比较特殊的运算符 比如 等号= 大于符号> 等 才要求 前后都有空格
    • 大小括号, 通常起始括号的前面有空格, 后面没有空格.

    github中有 两个 pull requests:

    • 一个是merged pull requests,
    • 另一个是 proposed pull requests.
      propose: 有多个 常用的意思
      打算, 计划; 建议, 提议; 提名, 推荐; 求婚(sb proposed to sb.)

    如何删除/修改github的用户名username 和 仓库?

    • Once you delete your account, there is no going back. Please be certain. 删除后 不能撤销, 请确信你要删除.
    • 删除用户名, 是在 用户的设置 > account 中修改username 和 account中删除账户
    • 修改仓库名: github默认的仓库名是 your_username.github.io, 你可以根据你的需要来修改为任何名字, 比如: your_username就可以直接作为仓库名称等.
    • 当然对 仓库和用户的修改, 必须是在 本用户的 sign in 状态下才可以进行.

    在 shell 终端中的 所有 命令 除了命令自身可以用 tab补齐/提示外, 命令的 双横线开头(单横线不行) 的选项options 也 是可以通过 tab键 单击两次 来提示的. 比如: ls/ll命令, --options补齐后, 其中: --directory就是只显示目录, 不显示文件; 而 --group-directories-first则是 分组显示, 目录优先
    vim中的光标跳转:
    help changelist 表示 当 变化发生时, 光标的位置会被记录: when making a change the cursor position is remembered.
    使用 g; 和 g, 可以将光标跳转到上一个/下一个变化的地点.

    ctrl +冒号, 显示之前的输入片段. ctrl+p显示 历史的输入单词


    在git中, 两个概念很重要:

    1. 工作区working space就是你init或clone时的那个目录, git的很多命令, 都需要(只能)在 工作区目录 下才能生效! (其他目录下git命令可能不能执行)
    2. 仓库. 就是工作区中 隐藏的那个子目录 .git (即 .git就是本地仓库)
    3. 工作区中的文件 要 commit 提交到 仓库, 需要先 staged (这个stage的意思, 本身是: 阶段; 舞台; 举行, 上演; 在这里的意思是: 驿站, 中间站, 扎营, "集结"), "changes not staged for commit" 修改变化没有 被 "集结" for 提交. 所以, 建议每次提交的时候, 不要单个文件的修改来提交, 应该是一天的工作结束了, 告一段落了, "集结"好了, 然后再一次性的commit.

    git目录中的内容, 要熟悉这些目录, 要能够在 工作区目录下, 直接操作 .git仓库里面的内容.

    • 主要包括6个目录: objects, refs | info, logs | branches, hooks
    • 5个文件: config, description | HEAD, index | packed-refs

    git目录下的hooks? 参考: https://git-scm.com/book/zh/v2/(自定义-git-git-钩子)%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90

    • hook 钩子: 在计算机中的钩子,是指当某个特定事件(动作/位置)发生时, 触发自定义的 脚本执行.
    • git钩子分为服务器端和客户端钩子, 客户端钩子是在.git/hooks/下的文件,主要是在 提交/合并等操作时的动作; 服务器端的钩子,是用于 接收 被其他机器上的推送 提交.
    • 开始时, 在.git/hooks下的钩子都是些 *.sample示例钩子, 用shell或python脚本都是可以的. 要使用钩子, 需要 正确命名和传入 参数...

    merge的位置? 可以是在不同的地方, 都可以进行合并:
    实际上, 可能在 本地机器上 将 分支和master 进行合并; 也可能是 将 远程机器上的仓库和 自己的github上的仓库进行 merge.

    git config 是一个命令, 配置可以直接在文件中写, 也可以用命令来配:

    1. 文件中采用的是 "节" 语法 比如: [core] 或 [brache "master"] 或 [remote "origin"]
    2. 如果是命令, 则采用 点语法, 比如: git config branch.master.remote "origin"
    • 要注意, 配置的格式是 git config key value key 和value中间是 没有等号的. 比如: git config http.postBuffer 524288000用要最大上传文件的 字节数 来表示, 不能是: git config http.postBuffer = 524288000 用等号是错误的

    • git config的操作: (它不只是配置, 设置, 还可以其他操作, 比如--get 获取配置值 -l --list 列出配置值)

    • git config --get key_name...
    • git config -e 可以打开对应的配置文件, 进行编辑
    • git config --unset 是删除某个配置 变量, 但是 该配置节 并不删除 --add则是添加
    • git config --remove-section 是删除某个配置节
    • 可以指定配置 变量的类型, --bool, --int --bool-or-int --path等.

    git的 fetch=+refs/heads/:refs/remotes/origin/?
    表示 fetch的动作 来源, 是: remotes/origin/* 的 所有分支!


    git status和 git diff的区别 而 git diff HEAD=git diff + git diff --cached

    1. git diff只是比较已经被 tracked的文件的变化changes
    2. 而 git status 不但能指出 没有被staged的文件changes 变化 / 没有被 committed 的文件 变化, 还可以指出没有被tracked的 新增文件 : 即 status = not staged changes/not committed changes + untracked files

    =============================================================================

    git log 是查看所有的提交历史, 但是如果要查看某个单独 的一个文件的提交历史, 使用-p选项: git log -p [file_name]

    gitk 只是 git提供的众多工具之一, 要安装其他的依赖包

    如果要用git来管理你的工作区/暂存区等 里面的文件, 那么就要使用 git...什么的 相应工具和命令 就是要告诉git你做了什么, 否则git就会不知道, 出现: git所记录的内容跟 实际目录中的内容不一致 而产生不可预知的错误. 比如要删除 工作区/暂存区中的文件, 使用 git rm就比较合适.

    <font color="red>

    关于git中的撤销文件修改?

    参考: https://www.cnblogs.com/zqlmmd/p/5541334.html https://blog.csdn.net/peisir/article/details/76939069这篇文章讲得较多
    所谓撤销修改, 就是当工作区的文件被 "改乱了", 我不想要 这些修改了.就用 这个"撤销 修改"
    分成 三级 撤销, 文件是被放在 workspace -> index区 -> repository中的, 所以 可以多级撤销:
    场景1: 只是改乱了 工作区中的文件, 并没有add到index, 可以用 git checkout -- file_name 来撤销, 此时是用 暂存区的文件来替换 工作区的文件???
    场景2: 改乱了工作区中的文件, 并且已经add到index了, 那么, 首先用 git reset HEAD 要撤销的文件 reset HEAD是用仓库中的内容来恢复. 这里由于只是指定了一个文件, 所以, 是用 仓库中的文件来恢复 index中的文件. 这里, 虽然index区的文件被恢复了, 但是 工作区的文件还没有撤销修改, 再用场景1的命令...
    场景3: 如果工作区中的修改已经 提交到本地仓库了, 那么就用 先前的版本来替换所有的, 就是 使仓库的 HEAD先前移动一次: git reset HEAD ^ 这时是恢复所有的, 撤销所以的东西.

    • git rm 会从工作区和暂存区中删除文件?? (如果要从本地仓库中删除, 还得要使用 提交: git rm filename, git commit...)如果只是想从 index区删除文件,(即不add 文件到暂存区): 使用git rm --cached [filename] 它是对git add 的撤销反命令.
    • git log可以看出哪些提交 和修改, 但是如果 当前版本被 重置 覆盖了, 那么git log就 看不到了, 如果要重新恢复 当前版本, 那么就要使用 git reflog( 表示 refered log 曾经被引用过 的那些 提交, 就可以看到被覆盖的 commitID了, 那么要 "版本回退" 就用 git reset commitID或 git reset HEAD~n 就好了.

    如何查看暂存区中有哪些文件? 用git status?

    再说终端颜色的设置? 参考: https://blog.csdn.net/ppdouble/article/details/50959305

    1. 关于颜色的设置: 颜色包括三个方面的内容, 即 "控制数字; 前景色; 背景色" 3个部分之间用 分号隔开, 前景色和背景色不分先后次序, 控制数字可以同时用多个不同的数字, 如: 0常规, 1加粗, 4下划线, 5闪烁, 7是反色 . 比如颜色是: e[1;4;7;42; 36m
    2. 注意用 echo printf跟 设置PS1的区别和不同:
      • 权限提示符 $ 在PS1中必须是两个反斜杠 \$ 才有效.
      • 其次, 在echo和printf中, 指定颜色时, 可以不用指示 "非打印字符序列" 的开始和结束, 但是 在PS1中 则必须要用 [ ] 来说明 "非打印字符序列" 的开始和结束. 否则会出现乱码.
        总之, 就是 用 PS1 来指定时, 要求更多 更严格.
    3. 关于PS1中的 中括号, 有三种不同的含义: 一是 "原本字符"按原样输出; 二是表示 non-printing chars sequence 非打印字符序列的开始和结束; 三是 用来表示颜色.

    格式是 先写颜色, 紧跟着写 要设置该颜色的字符内容.
    颜色表示: 从e[开始, 用 m 结束. 由于 要对[ 要进行转义, 所以实际的颜色表示是 e[颜色值m 要设置的内容 也可以用33 代替 e
    30~ 37 是前景色, 40~47是背景色 两者的相对应位置的颜色是一样的. 前景色和背景色可以同时指定, 用分号分隔, 而且不分先后.
    每次设置完颜色之后, 默认的后面所有的内容都会使用这种颜色 , 所以, 为了不影响/ 不污染 后面的内容 , 每次设置完成后 都应该恢复原装, 成默认值即0: e[0m
    设置 PS1之前, 可以用 echo -e 或 printf来测试 打印字符的颜色. 因为这两个命令本身也支持打印字符颜色.


    git commit foo_name 如果不加-m MESSAGE的话,会打开vim让你输入提交时的注释内容. 所以这个MeSSAGE是不能省略的. 那样更加不方便,所以记得在提交时输入注释.

    git中的点号".", 等同于当前目录下的所有文件, 相当于 -A, 比如: git add . 就是表示把当前工作区中的所有内容加入到index区

    revert是 恢复, 复原 使...回到之前的状态.

    git revert和git reset的区别?

    git diff的几种用法

    • 场景1: git diff 查看(工作区和index区都有的同名文件 之间 )当前没有被add to index的工作区修改
    • 场景2: git diff --cached 查看已经add但是没有被commit到本地仓库的修改.
    • git diff HEAD是 场景1和2 的合并.
    • git diff 版本1 版本2 src_folder: 比较两个版本号的src文件夹的差异.

    在git diff中, 有 a/filename 和 b/filename, 这里的a指的是远程的/暂存区的, b指的是暂存区/工作区的.

    =================================================

    git中的内容概念

    • 文件: file == hash 对应着 .git仓库中的Blob
    • 目录信息: directory == hash 对应着 tree
    • 提交: 牵一发而动全身, new-tree-of-top-tree == commit
    • 指向commit的指针 == refs
      中转然后到仓库: stage index,
      其他仓库的位置, 都叫做remotes(即使是在 同一台机器上 的其他仓库)
      打包 => pack

    commit包含的最重要的信息就是两个 top tree(顶级目录树)的SHA1名称 , 一个是 parent tree(父目录树[即: 上一次提交时的目录树]), 一个是当前目录树(current tree). 比较两个tree之间的不同, 就能知道这个 commit包含的变更内容.

    shell设置 git所在分支的 颜色表示: 参考: https://www.jianshu.com/p/82783f76a868 shell函数中的定义局部变量, 用 local. shell函数的用法跟 终端中对应的命令 的用法是完全一样的.

    1. 在shell中, 函数 === 命令, 函数就是命令, 是**自定义的命令. 只不过这个自定义命令的方式 就是用 function这个 关键字 而已! ** 既然函数就是命令, 所以, 在定义函数的时候, 是不需要加括号的, 在 调用/引用函数的时候, 也是不需要加括号的, 调用函数 跟使用命令的方式一样, 直接输入/传入 操作参数 (或 用 $1, $2...). 你甚至可以忘掉/或者说 shell中没有函数.
    2. 关于shell中的自定义命令(函数) 的返回值? 严格的说, shell函数的返回值只有 0 或1. 即函数执行后的结果状态值, 即 $?就是 所谓的 shell函数返回值.
      而要获得 传统意义上的 shell函数内部 输出的值 , 要用 local var_get_shell_return=反引号function_name 反引号 的方式, 实际上就是把shell函数的 输出到 标准屏幕的内容全部给予接收变量. shell函数输出的方式有多种: echo, printf, 或者 cut等都可以, 只要是标准输出有内容的都可以...
    3. 在PS1 中调用函数 , 不能使用 反引号的方式, 要使用 $( function_name) 的方式
    首先在 ~/.bashrc中 引入 一个单独的文件 .gitshell便于管理
    if [ -f /root/.gitshell ]; then
        . /root/.gitshell
    fi
    
    然后在 .gitshell中: 
    function git-branch-name { 
        git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3    // symbolic-ref HEAD 会输出 /refs/head/master之类的内容, 如果是在 非 .git目录下, 会输出错误但是丢弃 隐藏了.
    } 
        
    function git-branch-prompt {
     local branch=`git-branch-name`  ///shell函数默认定义的变量是 全局变量, 为了不污染shell环境, 用local显式声明是局部变量.
      if [ $branch ]; then
      printf " [%s]" $branch; fi
    } 
    
    PS1="u@h [33[0;36m]W[33[0m][33[1;32m]$(git-branch-prompt)[33[0m] \$ "
    
    

  • 相关阅读:
    GDB常用命令
    codevs1743
    Codeforces Round #369 (Div. 2)E
    Codeforces Round #200 (Div. 2)E
    2016 Multi-University Training Contest 4 T9
    2016 Multi-University Training Contest 1 T3
    2016 Multi-University Training Contest 1 T4
    HDU 5448 Marisa’s Cake
    codeforces 467C George and Job dp
    poj 1704 Georgia and Bob 博弈
  • 原文地址:https://www.cnblogs.com/bkylee/p/9248646.html
Copyright © 2011-2022 走看看