设为首页 收藏本站
查看: 1014|回复: 0

[经验分享] Git基本概念及操作(3)

[复制链接]

尚未签到

发表于 2018-9-18 12:36:02 | 显示全部楼层 |阅读模式
  如果使用传统的如CC开发的话,刚开始进行GIT开发可能不是太适应。这个主要是有些概念不一样。比喻在CC中,我们一般是围绕一个主分支进行开发,对一个文件来说,在主分支上会生成不同的版本。同样,我们在每一个版本下面创立新的次分支,在次分支上也会生出很多版本。最后合到主分支,产生下一个版本。那么在GIT中是如何实现这些关联呢?GIT中同样有分支、版本概念。但是没有Configspec概念。tag概念同LABEL概念类似。当然这些概念都同GIT中是如何管理文件版本相关的。首先我们来看GIT是如何将文件对象化管理的,前面我们说GIT同其它版本管理系统不一样是GIT每个版本都不是保存变更,而是全保存。那么如果全保存的话,显然会带来相当大的硬盘开销,其弊端非常明显,那么GIT是怎么消除这个弊端的呢?GIT利用了HASH算法,我们知道在目前已知道的算法中,HASH(SHA-1)算法产生的唯一性还是非常强的。也就是说虽然在工作区域是一个普通文件,但是在仓库中保存的是一个HASH值,由这个HASH值来表示文件,自然空间节省很多。GIT中将这个HASH值称之为对象。这些对象通常是由提交版本、子目录、文件的HASH值组成。对每一个对象通常按类型、大小和内容进行管理。其中最主要的是类型分为三种:
  1)blob 这种类型对象是用来存储文件数据,GIT中表现为一个HASH值,如下图所示:
DSC0000.png

  在以前GIT版本中会有一个单独的目录保存这些文件生成的HASH值通常是.git/objects/fc现在不在有这个fc目录,直接取生成的HASH的前两个值作目录。如下所示,注意在未提交之前,目录是不诞生对象。
  [root@wrlinux3 mygit]# git add .
  [root@wrlinux3 mygit]# ls -latr .git/objects/
  total 28
  drwxr-xr-x. 2 root root 4096 Apr 28 13:34 pack
  drwxr-xr-x. 2 root root 4096 Apr 28 13:34 info
  drwxr-xr-x. 2 root root 4096 Apr 28 13:35 f8
  drwxr-xr-x. 2 root root 4096 Apr 28 13:35 d2
  drwxr-xr-x. 2 root root 4096 Apr 28 13:35 52
  drwxr-xr-x. 7 root root 4096 Apr 28 13:35 ..
  drwxr-xr-x. 7 root root 4096 Apr 28 13:35 .
  [root@wrlinux3 mygit]# git hash-object README
  52c897fedf9f8728e953a149b7be3b5829a07b1c
  [root@wrlinux3 mygit]# git hash-object main.c
  f8b643afbf2c84dc03b777743d3e53a22045cf49
  [root@wrlinux3 mygit]# git hash-object testdir/test.c
  d22409509cd2f0a420e0cb6355008a9676656961
  [root@wrlinux3 mygit]# git show d224
  int test()
  {
  return 0;
  }
  [root@wrlinux3 mygit]# git show f8b6
  int main()
  {
  return 0;
  }
  [root@wrlinux3 mygit]# git show 52c8
  new readme
  [root@wrlinux3 mygit]# git cat-file -t 52c8
  blob
  [root@wrlinux3 mygit]# git cat-file -t f8b6
  blob
  [root@wrlinux3 mygit]# git cat-file -t d224
  blob
  2)tree 是一个simple 对象,它的内容就是一个指针表,指针指向的就是这个目录下的所有文件及子目录对象。也就是说这个对象记录了当前目录的元信息。如下图所示:
DSC0001.png

  正如前面所说,tree也是一串HASH值,这串HASH存储的是元信息。用来表示目录层次关系的。这和一般的SCM系统中是不一样,一般的SCM中目录同文件是一样的保存为版本对象的。
  [root@wrlinux3 mygit]# git commit -a -m "init commit"
  [master (root-commit) 4cfc524] init commit
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  3 files changed, 9 insertions(+)
  create mode 100644 README
  create mode 100644 main.c
  create mode 100644 testdir/test.c
  [root@wrlinux3 mygit]# ls -latr .git/objects/
  total 40
  drwxr-xr-x.  2 root root 4096 Apr 28 13:34 pack
  drwxr-xr-x.  2 root root 4096 Apr 28 13:34 info
  drwxr-xr-x.  2 root root 4096 Apr 28 13:35 f8
  drwxr-xr-x.  2 root root 4096 Apr 28 13:35 d2
  drwxr-xr-x.  2 root root 4096 Apr 28 13:35 52
  drwxr-xr-x.  2 root root 4096 Apr 28 14:12 bc
  drwxr-xr-x.  2 root root 4096 Apr 28 14:12 a8
  drwxr-xr-x.  2 root root 4096 Apr 28 14:12 4c
  drwxr-xr-x. 10 root root 4096 Apr 28 14:12 .
  drwxr-xr-x.  8 root root 4096 Apr 28 14:12 ..
  [root@wrlinux3 mygit]# ls -latr .git/objects/4c/fc5245433ac0b9277892ccb6e7bd4347aa01ec
  -r--r--r--. 1 root root 133 Apr 28 14:12 .git/objects/4c/fc5245433ac0b9277892ccb6e7bd4347aa01ec
  [root@wrlinux3 mygit]# ls -latr .git/objects/a8/8383ae64b09e71666adc12f4bf4760857f8c55
  -r--r--r--. 1 root root 115 Apr 28 14:12 .git/objects/a8/8383ae64b09e71666adc12f4bf4760857f8c55
  [root@wrlinux3 mygit]# ls -latr .git/objects/bc/a9ca7434467d22451fc370375dbab1a8930433
  -r--r--r--. 1 root root 51 Apr 28 14:12 .git/objects/bc/a9ca7434467d22451fc370375dbab1a8930433
  [root@wrlinux3 mygit]# git cat-file -t bca9
  tree
  [root@wrlinux3 mygit]# git cat-file -t a883
  tree
  [root@wrlinux3 mygit]# git cat-file -t 4cfc
  commit
  [root@wrlinux3 mygit]# git ls-tree bcag
  fatal: Not a valid object name bcag
  [root@wrlinux3 mygit]# git ls-tree bca9
  100644 blob d22409509cd2f0a420e0cb6355008a9676656961    test.c
  [root@wrlinux3 mygit]# git ls-tree a883
  100644 blob 52c897fedf9f8728e953a149b7be3b5829a07b1c    README
  100644 blob f8b643afbf2c84dc03b777743d3e53a22045cf49    main.c
  040000 tree bca9ca7434467d22451fc370375dbab1a8930433    testdir
  [root@wrlinux3 mygit]#
  3)commit 也是一种对象,但是这种对象存储是在提交这个点上的元信息,包括提交人、上次提交的版本对象指针及本次提交包含的树节点指针。如下图所示:
DSC0002.png

  看到这里可能还不是很明白。那我们将面连接起来如下所示:
DSC0003.png

  从这个图我们应该能够简单的明白了,在GIT中版本这种对象是在最高层,不像一般SCM中,对一个文件来说会记录不同的版本。而在GIT中不是这样的,它是对当下这个项目提交一个版本就进行一次快照。通俗的说就是一个版本包含当前快照下所有对象指针。这样从版本管理的角度来说,要管理的对象的是版本。不再是文件或者目录。这些东西统统可以缩成一个快照。如下图所示:
DSC0004.png

  在实际上可以使用如下命令查看:
  [root@wrlinux3 mygit]# git show -s --pretty=raw 4cfc
  commit 4cfc5245433ac0b9277892ccb6e7bd4347aa01ec
  tree a88383ae64b09e71666adc12f4bf4760857f8c55
  author ROOT root  1335593557 +0800
  committer ROOT root  1335593557 +0800
  init commit
  [root@wrlinux3 mygit]#
  通过上面的讲述我相信在Commit、Tree和Blob对象之三者的关系有了一个简单的认识,有人总结成了如下一张图,可以说是GIT实现的核心。
DSC0005.png

  从这张图我们也就明白了前面所说了Commit对象作为GIT管理的核心。GIT的Commit对象它不是说针对单个文件,它是针对的整个项目的。另外还有一种对象,TAG对象。TAG对象是用来标记特定的Commit的,如下图所示,这里可能还不能够清楚解析,后面学习了分支之后会比较清楚的了解。
DSC0006.png

  前面讲述了四种GIT对象,GIT对象是不可改变的(除了一些撤消操作之外),当然这里面的TAG对象有时候也可以称之为References引用,引用是可以移动,引用都是基本版本Commit对象的。因此从另外一个角度来说TAG也可以称之为引用。但实际上我们打了一个TAG之后是不能移动,他的特性与对象又一样。常用的引用主要分为分支、头、及远程分支。如下图所示:
DSC0007.png

  从上图可以看出,HEAD,BRACH,REMOTE,TAG最下层都是Commit对象,也就是GIT管理的粒度是以Commit来决定。Commit相当于一个快照。我们可以从git目录查看到这种组织方式。
  [root@wrlinux3 mygit]# cat .git/HEAD
  ref: refs/heads/master
  [root@wrlinux3 mygit]# ls -l .git/refs/
  total 8
  drwxr-xr-x. 2 root root 4096 Apr 28 14:12 heads
  drwxr-xr-x. 2 root root 4096 Apr 28 13:34 tags
  [root@wrlinux3 mygit]# ls -l .git/refs/tags/
  total 0
  [root@wrlinux3 mygit]# ls -l .git/refs/heads/
  total 4
  -rw-r--r--. 1 root root 41 Apr 28 14:12 master
  [root@wrlinux3 mygit]# cat .git/refs/heads/master
  4cfc5245433ac0b9277892ccb6e7bd4347aa01ec
  [root@wrlinux3 mygit]# git cat-file -t 4cfc
  commit
  [root@wrlinux3 mygit]#
  另外GIT也使用了优化算法,就是前面两个版本之间如果相同的对象没有发生改变的话,会直接采用链接的方式。如下图所示:
DSC0008.png

  这样就可以省去很多对象的产生。前面我们对Reference对象没有特别强调,只是强调他们是可以随着分支移动。这一点与很多SCM系统不同,比喻说CC,分支拉出来就固定,分支上生长出版本。而GIT不同,GIT上的分支它是随着版本移动的。我们来研究如下:
  1)分支 GIT中分支本质上是个指向Commit 对象的可变分支。默认情况下Git使用master作为分支的默认名字,每次一提交,master指针都会自动向前移动到下一个版本的commit对象上。当然你也可创建一个分支,使用命令git branch testing.如下图所示:
DSC0009.png

  可以通过仓库显示如下:
  [root@wrlinux3 mygit]# git branch testing
  [root@wrlinux3 mygit]# git branch
  * master
  testing
  [root@wrlinux3 mygit]# cat .git/HEAD
  ref: refs/heads/master
  [root@wrlinux3 mygit]# cat .git/refs/heads/master
  4cfc5245433ac0b9277892ccb6e7bd4347aa01ec
  [root@wrlinux3 mygit]# cat .git/refs/heads/testing
  4cfc5245433ac0b9277892ccb6e7bd4347aa01ec
  [root@wrlinux3 mygit]#
  这时我们可以看master和testing都指向4cfc Commit对象,同时master前面带有*号,HEAD中指向master,表示当前工作分支还在master上,如果想要在testing上工作,就必须修改HEAD指针。使用git checkout testing就可以切换了。
  [root@wrlinux3 mygit]# git checkout testing
  Switched to branch 'testing'
  [root@wrlinux3 mygit]# cat .git/HEAD
  ref: refs/heads/testing
  [root@wrlinux3 mygit]#
  这时HEAD指针指向Testing分支了。
DSC00010.png

  因为在GIT中创建和删除分支基本上不需要耗费计算机资源,因为分支在GIT表示的就是一个指向版本的指针(这个文件中保存的是版本对像的SHA值)。所以GIT是非常鼓励多建分支。那么很明显分支太多,也会带来版本合并的麻烦,所以一般来说建议尝试一个新功能在一个分支上开发完毕后,进行测试完成后就合并到主分支上再删除原来分支。下面我们围绕一个开发过程来进行分支的创建和合并。
DSC00011.png

  对应的版本图如下:
DSC00012.png

  对应的操作记录如下:
  [root@wrlinux3 mygit]# git checkout -b iss53
  Switched to a new branch 'iss53'
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git commit -a -m 'add new variable to calculate the value on branch [iss53]'
  [iss53 2f1f64e] add new variable to calculate the value on branch [iss53]
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 5 insertions(+), 1 deletion(-)
  [root@wrlinux3 mygit]# git checkout master
  Switched to branch 'master'
  [root@wrlinux3 mygit]# git checkout -b 'hotfix'
  Switched to a new branch 'hotfix'
  [root@wrlinux3 mygit]# git branch
  * hotfix
  iss53
  master
  testing
  [root@wrlinux3 mygit]# cd testdir/
  [root@wrlinux3 testdir]# vi test.c
  [root@wrlinux3 testdir]# git commit -a -m 'fixed the issue"
  [root@wrlinux3 testdir]# cd ..
  > ls
  > ^C
  [root@wrlinux3 testdir]# cd ..
  [root@wrlinux3 mygit]# ls
  main.c  README  testdir
  [root@wrlinux3 mygit]# git commit -a -m 'fixed the issue"
  > ^C
  [root@wrlinux3 mygit]# git commit -a -m 'fixed the issue'
  [hotfix 85412f9] fixed the issue
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 4 insertions(+), 1 deletion(-)
  [root@wrlinux3 mygit]# git checkout master
  Switched to branch 'master'
  [root@wrlinux3 mygit]# git merge hotfix
  Updating 4cfc524..85412f9
  Fast-forward
  testdir/test.c |    5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)
  [root@wrlinux3 mygit]# git branch -d hotfix
  Deleted branch hotfix (was 85412f9).
  [root@wrlinux3 mygit]# git branch
  iss53
  * master
  testing
  [root@wrlinux3 mygit]# vi testdir/test.c
  [root@wrlinux3 mygit]# git checkout master
  Already on 'master'
  [root@wrlinux3 mygit]# git merge iss53
  Merge made by the 'recursive' strategy.
  main.c |    6 +++++-
  1 file changed, 5 insertions(+), 1 deletion(-)
  [root@wrlinux3 mygit]# git merge iss53
  Already up-to-date.
  [root@wrlinux3 mygit]#
  通过GIT进行合并,因为是基本文本方式合并,可能不与CC中图形化直观,但是一定要注意两点,一点是DIFF工具可改,二点是MERGE前的工作区应该是干净的。当提示一些CONFLIC时需要手工打这些文件进行修改。
  [root@wrlinux3 mygit]# git mergetool
  No files need merging
  [root@wrlinux3 mygit]# git checkout testing
  Switched to branch 'testing'
  [root@wrlinux3 mygit]# ls
  main.c  README  testdir
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git commit -a -m "test comments"
  [testing d2569cb] test comments
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 1 insertion(+)
  [root@wrlinux3 mygit]# git checkout master
  Switched to branch 'master'
  [root@wrlinux3 mygit]# git mergetool
  No files need merging
  [root@wrlinux3 mygit]# git merge testing
  Auto-merging main.c
  CONFLICT (content): Merge conflict in main.c
  Automatic merge failed; fix conflicts and then commit the result.
  [root@wrlinux3 mygit]# git status
  # On branch master
  # Unmerged paths:
  #   (use "git add/rm ..." as appropriate to mark resolution)
  #
  #    both modified:      main.c
  #
  no changes added to commit (use "git add" and/or "git commit -a")
  [root@wrlinux3 mygit]# git merge testing
  error: 'merge' is not possible because you have unmerged files.
  hint: Fix them up in the work tree,
  hint: and then use 'git add/rm ' as
  hint: appropriate to mark resolution and make a commit,
  hint: or use 'git commit -a'.
  fatal: Exiting because of an unresolved conflict.
  [root@wrlinux3 mygit]# git status
  # On branch master
  # Unmerged paths:
  #   (use "git add/rm ..." as appropriate to mark resolution)
  #
  #    both modified:      main.c
  #
  no changes added to commit (use "git add" and/or "git commit -a")
  [root@wrlinux3 mygit]# git commit -a -m "commit stat"
  [master 5e453fa] commit stat
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  [root@wrlinux3 mygit]# git st
  # On branch master
  nothing to commit (working directory clean)
  前面讲了一些通用的分支操作,通过创建分支、合并分支并最终形成一个稳定的版本的过程,这个过程也是我们常见的SCM的管理职责,目前SCM人员需要制定主分支、开发分支、特性分支,通过管控这些分支来保证整个产品的质量的稳定。如下图所示:
DSC00013.png

  上图中不同的开发分支,代表了产品成熟的不同的周期。通过维护这些分支的生命周期来维护产品的生命周期。这里还需要强调的我们前面所进行的操作都是向有操作,也就是MERGE操作,实际上还有一种操作叫REBASE操作,rebase比较复杂,轻易不要使用,因为rebase会将当前已提交的版本历史给删除掉了,这样的话,一旦别人根据这些开发的话会产生丢失版本情况。如下图所示:
DSC00014.png

  对应的操作记录如下:
  [root@wrlinux3 mygit]# git branch experiment
  [root@wrlinux3 mygit]# git branch
  experiment
  * master
  [root@wrlinux3 mygit]# git checkout -b experiment
  fatal: A branch named 'experiment' already exists.
  [root@wrlinux3 mygit]# git checkout -B experiment
  Switched to and reset branch 'experiment'
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git commit -a -m 'commit on experiment'
  [experiment 774b7ee] commit on experiment
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 2 insertions(+), 3 deletions(-)
  [root@wrlinux3 mygit]# git checkout master
  Switched to branch 'master'
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git commit -a -m 'commit on master'
  [master cbe0f99] commit on master
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 1 insertion(+), 2 deletions(-)
  [root@wrlinux3 mygit]# gitk
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git commit -a -m 'commit on master more'
  [master 8f20d8c] commit on master more
  Committer: ROOT root
  Your name and email address were configured automatically based
  on your username and hostname. Please check that they are accurate.
  You can suppress this message by setting them explicitly:
  git config --global user.name "Your Name"
  git config --global user.email you@example.com

  After doing this, you may fix the>  git commit --amend --reset-author
  1 file changed, 1 insertion(+)
  [root@wrlinux3 mygit]# git checkout experiment
  Switched to branch 'experiment'
  [root@wrlinux3 mygit]# git rebase master
  It seems that there is already a rebase-apply directory, and
  I wonder if you are in the middle of another rebase.  If that is the
  case, please try
  git rebase (--continue | --abort | --skip)
  If that is not the case, please
  rm -fr /work/bongos/mygit/.git/rebase-apply
  and run me again.  I am stopping in case you still have something
  valuable there.
  [root@wrlinux3 mygit]# rm -fr /work/bongos/mygit/.git/rebase-apply
  [root@wrlinux3 mygit]# git rebase master
  First, rewinding head to replay your work on top of it...
  Applying: commit on experiment
  Using index info to reconstruct a base tree...
  Falling back to patching base and 3-way merge...
  Auto-merging main.c
  CONFLICT (content): Merge conflict in main.c
  Failed to merge in the changes.
  Patch failed at 0001 commit on experiment
  When you have resolved this problem run "git rebase --continue".
  If you would prefer to skip this patch, instead run "git rebase --skip".
  To check out the original branch and stop rebasing run "git rebase --abort".
  [root@wrlinux3 mygit]# vi main.c
  [root@wrlinux3 mygit]# git rebase --continue
  main.c: needs merge
  You must edit all merge conflicts and then
  mark them as resolved using git add
  [root@wrlinux3 mygit]# git add .
  [root@wrlinux3 mygit]# git rebase --continue
  Applying: commit on experiment
  [root@wrlinux3 mygit]# git st
  # On branch experiment
  nothing to commit (working directory clean)
  [root@wrlinux3 mygit]# gitk
  [root@wrlinux3 mygit]# git branch
  * experiment
  master
  [root@wrlinux3 mygit]#


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-589830-1-1.html 上篇帖子: Git 命令的冲突解决 下篇帖子: git是航空母舰:ScrumBoard
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表