美文网首页
Git命令实战操作

Git命令实战操作

作者: 奔跑吧李博 | 来源:发表于2023-11-11 10:53 被阅读0次
    git stash

    保存没有提交的修改

    git stash暂存
    git stash pop 使用最近一次暂存
    git stash save "xxx" 暂存时添加暂存信息
    git stash list 查看暂存列表
    git stash apply stash@{X} 回到某个暂存版本
    git stash drop stash@{X} 删除某个暂存版本
    git stash show stash@{X} 查看暂存版本详情
    git stash branch 从最新的stash创建分支
    

    示例:stash2个版本代码,然后查看stash版本列表,应用其中一个版本,删除其中一个版本。

    libo@libodeMacBook-Pro AlgorithmDeep % git stash list          
    libo@libodeMacBook-Pro AlgorithmDeep % git stash save "添加一个功能1"
    Saved working directory and index state On master: 添加一个功能1
    libo@libodeMacBook-Pro AlgorithmDeep % git stash save "删除了一个功能2"
    Saved working directory and index state On master: 删除了一个功能2
    libo@libodeMacBook-Pro AlgorithmDeep % git stash list
    stash@{0}: On master: 删除了一个功能2
    stash@{1}: On master: 添加一个功能1
    libo@libodeMacBook-Pro AlgorithmDeep % git stash apply stash@{1}
    On branch master
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   .idea/vcs.xml
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   app/src/main/java/com/example/algorithmdeep/Practise.java
    
    libo@libodeMacBook-Pro AlgorithmDeep % git stash drop stash@{0}
    Dropped stash@{0} (3c4d22d1252eb2f067ad2f30cff69f72dfff3672)
    libo@libodeMacBook-Pro AlgorithmDeep % git stash list
    stash@{0}: On master: 添加一个功能1
    
    git reset

    git reset 命令格式为:
    git reset [ --soft | --mixed | --hard ] [< commitid >]

    soft:
    –soft参数只将其它的commit重置到你选定的HEAD,index和working copy中的数据不变。
    mixed:
    –mixed参数是将HEAD和index重置到你选定的HEAD,而working copy不变。
    hard:
    –hard是将HEAD,index,working copy同时改变到你规定的commit上。
    

    示例:抛弃工作区间不需要改动,代码回到上一次提交状态:

    libo@libodeMacBook-Pro AlgorithmDeep % git status
    On branch master
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   .idea/vcs.xml
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   app/src/main/java/com/example/algorithmdeep/Practise.java
    
    libo@libodeMacBook-Pro AlgorithmDeep % git reset --hard
    HEAD is now at 828b07b init commit
    
    git log
    • git log 查看各次提交信息
    libo@libodeMacBook-Pro AlgorithmDeep % git log
    commit 4a0a889808b21db5ec2c056209ceaf1bd7e34abf (HEAD -> master)
    Author: libo <libo31@xiaomi.com>
    Date:   Sun Nov 26 11:10:09 2023 +0800
    
        新增detectCycle代码
    
    commit 8804579282019db1def1d4ec5a0970a445c18daa
    Author: libo <libo31@xiaomi.com>
    Date:   Sun Nov 26 11:09:05 2023 +0800
    
        新增levelOrder代码
    
    commit 828b07b94e9598f5442f452f734bcecbc3cdfd3a
    Author: libo <libo31@xiaomi.com>
    Date:   Sun Nov 26 10:53:27 2023 +0800
    
        init commit
    
    
    • git log --oneline 选项来查看历史记录的简洁的版本
    libo@libodeMacBook-Pro AlgorithmDeep % git log --oneline
    4a0a889 (HEAD -> master) 新增detectCycle代码
    8804579 新增levelOrder代码
    828b07b init commit
    
    合并多个commit

    方法:git rebase

    # 查看前10个commit
    git log -10
    # 运行 `git rebase` 命令,并指定需要合并的提交范围。如果你想要合并最近的 3 个提交,可以使用以下命令:
    git rebase -i HEAD~3
    或者
    git rebase -i 开始commit 结束commit
    # 强制push以替换远程仓的commitID
    git push --force
    

    参考:https://blog.csdn.net/wangdawei_/article/details/131669124

    git rebase -i HEAD~2    
    pick 8804579 新增levelOrder代码
    pick 4a0a889 新增detectCycle代码
    # Rebase 828b07b..4a0a889 onto 828b07b (2 commands)
    
    Successfully rebased and updated refs/heads/master.
    
    git diff

    用于比较两次修改的差异

    1.1 比较工作区与暂存区
    git diff 不加参数即默认比较工作区与暂存区

    1.2 比较暂存区与最新本地版本库(本地库中最近一次commit的内容)
    git diff --cached [<path>...]

    1.3 比较工作区与最新本地版本库
    git diff HEAD [<path>...] 如果HEAD指向的是master分支,那么HEAD还可以换成master

    1.4 比较工作区与指定commit-id的差异
    git diff commit-id [<path>...]

    1.5 比较暂存区与指定commit-id的差异
    git diff --cached [<commit-id>] [<path>...]

    1.6 比较两个commit-id之间的差异
    git diff [<commit-id>] [<commit-id>]

    1.7 比较两个分支上最后 commit 的内容的差别
    git diff <分支名1> <分支名2>

    参考:https://www.runoob.com/git/git-diff.html

    git commit --amend

    合并这次提交到上一次commit里面,并且可以修改commit message。

    新增detectCycle代码
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Sun Nov 26 11:10:09 2023 +0800
    #
    # On branch master
    # No commands done.
    # Next command to do (1 remaining command):
    #    pick 4a0a889 新增detectCycle代码
    # You are currently editing a commit during a rebase.
    #
    # Changes to be committed:
    #       modified:   app/src/main/java/com/example/algorithmdeep/Practise.java
    :wq
    
    git cherry-pick

    cherry-pick命令常用于以下场景:
    1.合并单个提交:当我们只想应用某个分支上的一个提交到当前分支时,可以使用cherry-pick命令,而不需要合并整个分支。
    2.修复bug:当我们在一个分支上修复了一个bug,并希望将这个修复应用到其他分支上时,可以使用cherry-pick命令。
    3.提取特定功能:当我们在一个分支上开发了一个新功能,并希望将该功能应用到其他分支上时,可以使用cherry-pick命令。

    git cherry-pick <commit>
    

    示例:在主分支新增了提交,在feature分支使用git cherry-pick <commit>去拉取合并这一个提交。

    libo@libodeMacBook-Pro AlgorithmDeep % git branch feature
    libo@libodeMacBook-Pro AlgorithmDeep % git commit -a -m "主分支提交功能"  
    [master 00e8af2] 主分支提交功能
     1 file changed, 4 insertions(+)
    libo@libodeMacBook-Pro AlgorithmDeep % git checkout feature
    Switched to branch 'feature'
    libo@libodeMacBook-Pro AlgorithmDeep % git cherry-pick 00e8af2
    [feature e0017ec] 主分支提交功能
     Date: Sun Nov 26 11:40:27 2023 +0800
     1 file changed, 4 insertions(+)
    
    git merge和git rebase

    git rebase和git merge这两个命令都旨在将更改代码从一个分支合并到另一个分支,但二者的合并方式却有很大的不同。

    Git merge 将两个分支中的所有提交都合并到一起,并创建一个新的合并提交,保留了历史记录。这导致了 Git 历史记录中出现多个分支合并点的情况,从而使历史记录更加复杂。
    Git rebase 是将一个分支的提交序列“拉直”,并且将其与另一个分支合并。这意味着,提交历史看起来好像是一条直线,没有分叉,因此整个提交历史看起来更加整洁,历史记录保持相对简单。

    总的来说,Git rebase 可以提供更整洁的提交历史,但它需要更多的注意力和精细的操作,因为它可能导致原有的提交变得不可用。Git merge 则是更为保守的合并方法,它更简单,但历史记录更加复杂。因此,选择哪种方法取决于团队和项目的需求和偏好。

    场景:

    假设当前我们有master和feature分支,当你在专用分支上开发新 feature 时,然后另一个团队成员在 master 分支提交了新的 commits,这种属于正常的Git工作场景。

    此时是无法push到远程仓库的,需要进行分支合并,下面来演示git rebase 和 git merge 这两个命令的差异。

    1、git merge

    操作:

    git checkout feature
    git merge master
    

    由上图可知,git merge 会在 feature 分支中新增一个新的 merge commit,然后将两个分支的历史联系在一起

    • 使用 merge 是很好的方式,因为它是一种非破坏性的操作,对现有分支不会以任何方式被更改。
    • 另一方面,这也意味着 feature 分支每次需要合并上游更改时,它都将产生一个额外的合并提交。
    • 如果master 提交非常活跃,这可能会严重污染你的 feature 分支历史记录。
    2. git rebase
    git checkout feature
    git rebase master
    
    • rebase 会将整个 feature 分支移动到 master 分支的顶端,从而有效地整合了所有 master 分支上的提交。

    • 与 merge 提交方式不同,rebase 通过为原始分支中的每个提交创建全新的 commits 来重写项目历史记录,特点是仍然会在feature分支上形成线性提交

    • rebase的主要好处就是历史记录更清晰,没有不必要的合并提交,提交历史看起来好像是一条直线,没有分叉。

    libo@libodeMacBook-Pro AlgorithmDeep % git checkout feature
    Switched to branch 'feature'
    libo@libodeMacBook-Pro AlgorithmDeep % git rebase master
    Auto-merging app/src/main/java/com/example/algorithmdeep/Practise.java
    CONFLICT (content): Merge conflict in app/src/main/java/com/example/algorithmdeep/Practise.java
    error: could not apply 4a0a889... 新增detectCycle代码
    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 4a0a889... 新增detectCycle代码
    Could not apply 53a0a17... feature分支提交功能3
    libo@libodeMacBook-Pro AlgorithmDeep % git rebase --continue
    app/src/main/java/com/example/algorithmdeep/Practise.java: needs merge
    You must edit all merge conflicts and then
    mark them as resolved using git add
    libo@libodeMacBook-Pro AlgorithmDeep % git add .
    libo@libodeMacBook-Pro AlgorithmDeep % git rebase --continue
    [detached HEAD 17fcbb1] feature分支提交功能3
     1 file changed, 5 insertions(+)
    Successfully rebased and updated refs/heads/feature.
    

    rebase之后,两个分支的两个条线,就融合成了一条提交线:


    如何选择git merge和git rebase?

    git merge优点是分支代码合并后不破坏原分支的代码提交记录,缺点就是会产生额外的提交记录并进行两条分支的合并,

    git rebase 优点是无须新增提交记录到目标分支,rebase后可以将对象分支的提交历史续上目标分支上,形成线性提交历史记录,进行review的时候更加直观

    git merge 如果有多人进行开发并进行分支合并,会形成复杂的合并分支图,比如:

    总结:
    融合个人分支到主分支的时使用git merge,而不用git rebase
    融合主分支到个人分支的时候使用git rebase,可以不污染分支的提交记录,形成简洁的线性提交历史记录。

    参考:
    https://joyohub.com/2020/04/06/git-rebase/

    https://www.bilibili.com/video/BV1Xb4y1773F/?spm_id_from=333.337.search-card.all.click&vd_source=40c24e77b23dc2e50de2b7c87c6fed59

    相关文章

      网友评论

          本文标题:Git命令实战操作

          本文链接:https://www.haomeiwen.com/subject/cxikwdtx.html