zoukankan      html  css  js  c++  java
  • 斐波那契数列为例的 git 实战

    本文创设一个情景:斐波那契数列求法的实现,来演练 git 和 github 的使用。斐波那契数列的介绍参见 [2],其不同时空复杂度的实现见 [3]。

    步骤一:在 github 上建立一个远程仓库

    github 现在要勾选好多东西才能创建仓库了。这些勾勾,勾了之后就会生成 .gitgnore,README.md。建立好远程仓库,github 会自动跳转到仓库页面。绿绿的 Code 按钮点开能看到仓库地址。接下来把仓库 clone 到本地。

    对 c/c++ 项目来说,Windows 下用命令行工具的话,首选 VS Developer Command Prompt。此工具会设置好 c/c++ 编译链接需要的路径。从这玩意打开 VSCode (这也是 VSCode Doc 里面推荐的做法,见 [4]),创建 task.json 的时候会自动设置好,很爽。如果你想像我一样作死看看直接用 cmd 需要配置多少编译和链接路径,劝你放弃。

    **********************************************************************
    ** Visual Studio 2019 Developer Command Prompt v16.7.4
    ** Copyright (c) 2020 Microsoft Corporation
    **********************************************************************
    
    D:Projects>git clone https://github.com/tandandanw/fibonacci.git
    Cloning into 'fibonacci'...
    remote: Enumerating objects: 4, done.
    remote: Counting objects: 100% (4/4), done.
    remote: Compressing objects: 100% (4/4), done.
    remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
    Unpacking objects: 100% (4/4), 941 bytes | 4.00 KiB/s, done.
    
    D:Projects>cd fibonacci
    
    D:Projectsfibonacci>code .
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    nothing to commit, working tree clean
    
    

    在 github 仓库页面 Insights >> Network,可以看到 Network graph,显示仓库的 commits timeline。

    步骤二:修改 master 主分支

    在 VSCode 中打开项目之后,新建一个 fibo.c 文件,键入基本的框架代码:只包含计算斐波那契数列的函数和主函数。

    #include <stdio.h>
    
    int fibonacci(int n)
    {
        return -1;
    }
    
    int main(int args, char *argv[])
    {
        int n; scanf("%d", &n);
        int result = fibonacci(n);
        printf("%d", result);
    
        return 0;
    }
    

    这时候再看看 status 就会发现此文件已经变成了 Untracked files 的一员。再执行 add 命令,fibo.c 就暂存到了 Index 区。

    D:Projectsfibonacci>git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            fibo.c
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    D:Projectsfibonacci>git add fibo.c
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is up to date with 'origin/master'.    
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   fibo.c
    

    如果要把 fibo.c 从 Index 里移除,使用 reset 命令。只有 Index 中的文件才会在提交代码时存入版本库。

    D:Projectsfibonacci>git reset HEAD fibo.c
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            fibo.c
    
    nothing added to commit but untracked files present (use "git add" to track)
    

    为了确保代码运行正确,先编译一下。 因为现在只有一个文件,所以直接在当前目录下编译生成 .exe文件。如果 setting.json 里面没有给终端设置一下七七八八的参数的话,直接在 VSCode 的菜单里 Terminal >> Configure Default Build Task 一路回车就可以生成默认的 tasks.json。然后把鼠标切回 fibo.c ,按下 Ctrl + Shift + B 就可以编译了。结果如下:

    > Executing task: cl.exe /Zi /EHsc /Fe: d:Projectsfibonaccifibo.exe d:Projectsfibonaccifibo.c <
    
    Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    fibo.c
    Microsoft (R) Incremental Linker Version 14.27.29111.0    
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /debug
    /out:d:Projectsfibonaccifibo.exe
    fibo.obj
    
    Terminal will be reused by tasks, press any key to close it.
    

    运行一下 fibo.exe,不出意外的话无论输入什么结果都是 -1。

    D:Projectsfibonacci>fibo.exe
    1
    -1
    D:Projectsfibonacci>fibo.exe
    5
    -1
    D:Projectsfibonacci>fibo.exe
    100000
    -1
    

    现在我们用 dir 和 status 观察一下当前的文件。

    D:Projectsfibonacci>dir
     Volume in drive D is Working Disk
     Volume Serial Number is 584C-873F
    
     Directory of D:Projectsfibonacci
    
    2020/10/01  22:23    <DIR>          .
    2020/10/01  22:23    <DIR>          ..
    2020/10/01  16:46               482 .gitignore     
    2020/10/01  22:17    <DIR>          .vscode        
    2020/10/01  22:26               445 fibo.c
    2020/10/01  22:23           494,080 fibo.exe       
    2020/10/01  22:23         2,045,228 fibo.ilk       
    2020/10/01  22:23             5,907 fibo.obj       
    2020/10/01  22:23         9,605,120 fibo.pdb       
    2020/10/01  16:46                52 README.md      
    2020/10/01  22:23            77,824 vc140.pdb      
                   8 File(s)     12,229,138 bytes      
                   3 Dir(s)  483,415,437,312 bytes free
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            .vscode/
            fibo.c
    
    nothing added to commit but untracked files present (use "git add" to track)
    

    为什么 Untracked files 里面没有出现编译的中间文件 .obj 之流呢?因为 .gitgnore 里设置了啥文件不加入版本控制。一般来说版本控制里不应当加入的是可以用已有文件生成的文件(体会一下)。是时候了,现在第一个版本已经好了,用 commit 命令提交新版本。提交后用 log 命令可以看到当前版本前所有的版本提交信息。可以看到,我们本地的 master 分支已经比远程 origin 的 master 前进了一个版本。如果想要回退到前一个版本,可以使用 reset —hard HEAD^。回退命令的 --hard 参数后面可以有很多种表示方式,详情键入 git help reset 查阅。此时想要查看“未来”的版本需要使用 reflog 命令。

    D:Projectsfibonacci>git commit -m "Create empty framework" 
    [master fa3dafe] Create empty framework
     1 file changed, 20 insertions(+)      
     create mode 100644 fibo.c
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            .vscode/
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    D:Projectsfibonacci>git log
    commit fa3dafe3618c5fc874b8bdf1f844a0b0d85c0f7a (HEAD -> master)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Thu Oct 1 22:38:46 2020 +0800
    
        Create empty framework
    
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit
    
    D:Projectsfibonacci>git reset --hard HEAD^^
    HEAD is now at 8cc6340 Initial commit
    
    D:Projectsfibonacci>git log
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (HEAD -> master, origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit
    
    D:Projectsfibonacci>git reflog
    8cc6340 (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: reset: moving to HEAD^
    fa3dafe HEAD@{1}: reset: moving to HEAD
    fa3dafe HEAD@{2}: commit: Create empty framework
    8cc6340 (HEAD -> master, origin/master, origin/HEAD) HEAD@{3}: clone: from https://github.com/tandandanw/fibonacci.git
    
    D:Projectsfibonacci>git reset --hard fa3d
    HEAD is now at fa3dafe Create empty framework
    
    

    (此处出现了一个问题,键入 HEAD^ 的时候这个 VS Prompt 问我 More? 查了一下是因为 cmd 中换行符默认是 ^ 而不是 ,所以它愚蠢地以为还有下一行。解决方案见 [5])

    步骤三:增加一个分支

    增加分支之前,我又给 master 增加了几个版本。每个版本增加的功能都应该干净、简单。而且要在对应的 commit log message 里面描述清楚。目前的版本树如下:

    commit bb9e88a77c054b4d48991109ffceb8ad21b0fc46 (HEAD -> master)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 10:38:35 2020 +0800
    
        Add assert for safety
    
    commit 4d557ffde86633cba27051d5646d8c1948457496
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 10:34:25 2020 +0800
    
        Add timer and multi-times calculation
    
    commit b29bc4d0edf17f3a1c745e141b7670ca543fe4f4
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 10:22:02 2020 +0800
    
        Redirect stdin to file input
    
    commit 9821de541f3f6da4faac33be803b7ea2610f4c83
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 10:19:10 2020 +0800
    
        Add single argument implementation
    
    commit a5a5ea39bd21d01f8ca5d5a1ecd9732824f5e51e
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 10:10:08 2020 +0800
    
        Filter vscode config files
    
    commit fa3dafe3618c5fc874b8bdf1f844a0b0d85c0f7a
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Thu Oct 1 22:38:46 2020 +0800
    
        Create empty framework
    
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit
    
    

    接下来为了创建分支,先回退到最开始的版本。然后使用 checkout 命令创建新分支。

    D:Projectsfibonacci>git reset --hard fa3d
    HEAD is now at fa3dafe Create empty framework
    
    D:Projectsfibonacci>git checkout -b tddbranch
    Switched to a new branch 'tddbranch'
    
    D:Projectsfibonacci>git branch
      master
    * tddbranch
    
    

    现在可以在新建分支里继续和 master 不一样的版本更新了。我又加了几个版本之后,log 如下:

    commit 170ae6bfd7816f63e17e32573b8a8d74c8575847 (HEAD -> tddbranch)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:07:51 2020 +0800
    
        Add assert
    
    commit 5d5d8e81a578834e3c52a2934be8c6bc11e36766
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:06:29 2020 +0800
    
        Add timer and times
    
    commit d7afacfaaa95b454f564bc07f140a266eb36a358
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:04:43 2020 +0800
    
        Redirect stdin to file
    
    commit 814bb007c24055996a4bc82b369de13455527563
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:01:41 2020 +0800
    
        Add binet formula implementation
    
    commit fa3dafe3618c5fc874b8bdf1f844a0b0d85c0f7a (master)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Thu Oct 1 22:38:46 2020 +0800
    
        Create empty framework
    
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit
    

    然后可以用 rebase 命令来整理一下提交记录。指定 -i 会在命令行打开一个 vi 的文本编辑器编辑提交记录。

    D:Projectsfibonacci>git rebase -i "HEAD^^^"
    
    pick d7afacf Redirect stdin to file
    pick 5d5d8e8 Add timer and times
    pick 170ae6b Add assert
    
    # Rebase 814bb00..170ae6b onto 814bb00 (3 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup <commit> = like "squash", but discard this commit's log message
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    # l, label <label> = label current HEAD with a name
    # t, reset <label> = reset HEAD to a label
    # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
    # .       create a merge commit using the original merge commit's
    # .       message (or the oneline, if no original merge commit was
    # .       specified). Use -c <commit> to reword the commit message.
    #
    # 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.
    #
    ~   
    

    这时如果把第二行删掉,保存之后,当前的 HEAD 会变成第一行的版本,即将写入的版本是第三行。cmd 显示如下:

    "D:/Projects/fibonacci/.git/rebase-merge/git-rebase-todo" [converted][unix] 27L, 1152C written
    error: could not apply 170ae6b... Add assert
    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 170ae6b... Add assert
    Auto-merging fibo.c
    CONFLICT (content): Merge conflict in fibo.c
    

    在 VSCode 里可以对冲突的地方进行修改,或直接编辑文件。完成修改后用 add 冲突文件到 Index,再用 rebase -- continue 命令完成操作。再看 log 发现已经消失了一个版本。

    D:Projectsfibonacci>git add fibo.c
    
    D:Projectsfibonacci>git rebase --continue
    
    Add assert
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # interactive rebase in progress; onto 814bb00
    # Last commands done (2 commands done):
    #    pick d7afacf Redirect stdin to file
    #    pick 170ae6b Add assert
    # No commands remaining.
    # You are currently rebasing branch 'tddbranch' on '814bb00'.
    #
    # Changes to be committed:
    #       modified:   fibo.c
    #
    # Untracked files:
    #       .vscode/
    #
    ~
    
    "D:/Projects/fibonacci/.git/COMMIT_EDITMSG" [converted][unix] 18L, 477C written
    
    [detached HEAD 7da34b8] Add assert
     1 file changed, 24 insertions(+), 8 deletions(-)
    Successfully rebased and updated refs/heads/tddbranch.
    
    D:Projectsfibonacci>git log
    commit 7da34b84207bbc75a9ad2bd2f952123ea25267fa (HEAD -> tddbranch)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:07:51 2020 +0800
    
        Add assert
    
    commit d7afacfaaa95b454f564bc07f140a266eb36a358
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:04:43 2020 +0800
    
        Redirect stdin to file
    
    commit 814bb007c24055996a4bc82b369de13455527563
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:01:41 2020 +0800
    
        Add binet formula implementation
    
    commit fa3dafe3618c5fc874b8bdf1f844a0b0d85c0f7a (master)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Thu Oct 1 22:38:46 2020 +0800
    
        Create empty framework
    
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit                                                                                                                    
    

    步骤四:合并

    进行合并操作之前,切到 master 分支,先 pull 同步远程仓库,再 merge。这里使用 --no--ff 关闭快进合并(fast-farward merge)防止分支被覆盖。编辑解决冲突之后,push 到远程仓库中。

    
    D:Projectsfibonacci>git checkout master
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    
    D:Projectsfibonacci>git pull
    Already up to date.
    
    D:Projectsfibonacci>git merge --no-ff tddbranch
    Merge made by the 'recursive' strategy.
     data.txt |  6 ++++++
     fibo.c   | 47 ++++++++++++++++++++++++++++++++++++++---------
     2 files changed, 44 insertions(+), 9 deletions(-)
     create mode 100644 data.txt
    
    D:Projectsfibonacci>git log
    commit cd6adc784d38ac56ab2c7a2c51d13f63c58737fe (HEAD -> master)
    Merge: fa3dafe 7da34b8
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 12:35:12 2020 +0800
    
        Merge branch 'tddbranch'
    
    commit 7da34b84207bbc75a9ad2bd2f952123ea25267fa (tddbranch)
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:07:51 2020 +0800
    
        Add assert
    
    commit d7afacfaaa95b454f564bc07f140a266eb36a358
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:04:43 2020 +0800
    
        Redirect stdin to file
    
    commit 814bb007c24055996a4bc82b369de13455527563
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Sat Oct 3 11:01:41 2020 +0800
    
        Add binet formula implementation
    
    commit fa3dafe3618c5fc874b8bdf1f844a0b0d85c0f7a
    Author: tandandanw <tandandanw@gmail.com>
    Date:   Thu Oct 1 22:38:46 2020 +0800
    
        Create empty framework
    
    commit 8cc6340840c711802141ce26c4a47f3dfad7ee76 (origin/master, origin/HEAD)
    Author: tandandan <passerbytandd@gmail.com>
    Date:   Thu Oct 1 16:32:18 2020 +0800
    
        Initial commit
    
    D:Projectsfibonacci>git status
    On branch master
    Your branch is ahead of 'origin/master' by 5 commits.
      (use "git push" to publish your local commits)
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            .vscode/
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    D:Projectsfibonacci>git push
    Enumerating objects: 15, done.
    Counting objects: 100% (15/15), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (13/13), done.
    Writing objects: 100% (14/14), 1.98 KiB | 1011.00 KiB/s, done.
    Total 14 (delta 7), reused 0 (delta 0), pack-reused 0
    remote: Resolving deltas: 100% (7/7), done.
    To https://github.com/tandandanw/fibonacci.git
       8cc6340..cd6adc7  master -> master
    

    此时本地的 reflog 输出如下(试错操作很多问题T.T):

    D:Projectsfibonacci>git reflog
    cd6adc7 (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: reset: moving to cd6a
    9473fac HEAD@{1}: reset: moving to 9473
    cd6adc7 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: reset: moving to cd6a
    4d557ff HEAD@{3}: reset: moving to 4d55
    bb9e88a HEAD@{4}: reset: moving to bb9e
    fa3dafe HEAD@{5}: rebase (finish): returning to refs/heads/master
    fa3dafe HEAD@{6}: rebase (start): checkout HEAD^^
    9473fac HEAD@{7}: rebase (finish): returning to refs/heads/master
    9473fac HEAD@{8}: rebase (start): checkout HEAD^
    9473fac HEAD@{9}: reset: moving to HEAD
    9473fac HEAD@{10}: commit: After merge
    fa3dafe HEAD@{11}: reset: moving to fa3d
    cd6adc7 (HEAD -> master, origin/master, origin/HEAD) HEAD@{12}: merge tddbranch: Merge made by the 'recursive' strategy.
    fa3dafe HEAD@{13}: checkout: moving from tddbranch to master
    7da34b8 (tddbranch) HEAD@{14}: rebase (continue) (finish): returning to refs/heads/tddbranch
    7da34b8 (tddbranch) HEAD@{15}: rebase (continue): Add assert
    d7afacf HEAD@{16}: rebase (start): checkout HEAD^^^
    170ae6b HEAD@{17}: commit: Add assert
    5d5d8e8 HEAD@{18}: commit: Add timer and times
    d7afacf HEAD@{19}: commit: Redirect stdin to file
    814bb00 HEAD@{20}: commit: Add binet formula implementation
    fa3dafe HEAD@{21}: checkout: moving from master to tddbranch
    fa3dafe HEAD@{22}: reset: moving to fa3d
    bb9e88a HEAD@{23}: commit: Add assert for safety
    4d557ff HEAD@{24}: commit: Add timer and multi-times calculation
    b29bc4d HEAD@{25}: commit: Redirect stdin to file input
    9821de5 HEAD@{26}: commit: Add single argument implementation
    a5a5ea3 HEAD@{27}: commit: Filter vscode config files
    fa3dafe HEAD@{28}: reset: moving to fa3d
    8cc6340 HEAD@{29}: reset: moving to HEAD^
    fa3dafe HEAD@{30}: reset: moving to HEAD
    fa3dafe HEAD@{31}: commit: Create empty framework
    8cc6340 HEAD@{32}: clone: from https://github.com/tandandanw/fibonacci.git
    

    时间线如下图。可以看到,非快进式 merge 了分支里的代码到 master 里。我之前在本地 master 里增加的版本,因为没有 push,所以在本地能够查看,在远程不能。

    步骤五:等待别人的 fork 然后处理 request



    其他

    搜索分支命名规范的时候,找到了 [6],可以一看。实际应用中应该各有各的规范,到时再学习就好。工具类的东西,即用即学。

    项目地址在

    本篇博客写在电脑键盘部分损毁时,费时费力。还是熟悉了一下之前确实没怎么用过的命令。

    参考

    [1] https://mp.weixin.qq.com/s/Km5KuXPETvG0wCGHrvj9Vg
    [2] https://zh.wikipedia.org/wiki/斐波那契数列
    [3] https://leetcode-cn.com/problems/fibonacci-number/solution/
    [4] https://code.visualstudio.com/docs/cpp/config-msvc
    [5] https://blog.csdn.net/qq_32623363/article/details/78968077
    [6] https://juejin.im/post/6844903635533594632

  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/tandandan/p/13758241.html
Copyright © 2011-2022 走看看