详解git submodule update获取不到最新提交的代码_其它综合

来源:脚本之家  责任编辑:小易  

对于一个较大的Git工程,2113你可能会5261想在多个仓库之间4102共享代码,不管这些代码是在多个不同1653产品间使用的项目共享库或是一些模板。Git通过子模块来实现这样的需求。子模块允许将其他代码仓库的克隆作为子目录放到一个父仓库(有时候也称为父项目)中。一个子模块也是一个独立的仓库,你可以像其他仓库一样执行commit,branch,rebase等等操作。JGit提供了实现大部分Git子模块命令的API。我将在这儿给大家介绍这些API。设置本文中用到的代码片段将作为学习测试程序。简单的测试程序有助于理解第三方库是如何工作,以及如何使用新的API。你可以将这些测试程序看做是可控制的试验,帮助你更加直观地发现第三方代码是如何执行的。除此之外,如果你保持编写测试程序,可以帮助你检验第三方代码的新版本。如果你的测试程序涵盖了如何调用这些库,那么第三方代码中不兼容的修改将会尽早展现出来。回到之前的话题,所有的测试程序共享同一个设置,详细信息请查看源代码。现在有一个空的仓库,叫parent,以及另一个仓库叫library。测试程序中,library将会作为子模块添加到parent仓库中。library仓库初始化提交了一个readme.txt文件。测试程序中有一个setUp方法,用来创建这两个仓库,如下所示:1Git git = Git.init().setDirectory( "/tmp/path/to/repo" ).call();这两个仓库用类型为Git的parent和library变量表示。该类封装了一个仓库并允许访问JGit的所有可用指令。就如较早之前我在这里中提到,每个Commnad类对应于一条原生的Git pocelain指令。调用一个指令需要用到生成器模式。举个例子,执行Git.commit()的结果实际上相当于一个CommitCommand。你可以提供一些必要的参数去调用它的call()方法,从而执行相应的指令。添加一个子模块第一步当然是在一个已有的仓库添加子模块。通过上面提到的setUp步骤,library仓库应当作为子模块添加到parent仓库的modules/library目录下。12345678910111213141516@Testpublic void testAddSubmodule() throws Exception {String uri= library.getRepository().getDirectory().getCanonicalPath();SubmoduleAddCommand addCommand = parent.submoduleAdd();addCommand.setURI( uri );addCommand.setPath( "modules/library" );Repository repository = addCommand.call();repository.close();F‌ile workDir = parent.getRepository().getWorkTree();F‌ile readme = new F‌ile( workDir, "modules/library/readme.txt" );F‌ile gitmodules = new F‌ile( workDir, ".gitmodules" );assertTrue( readme.isF‌ile() );assertTrue( gitmodules.isF‌ile() );}SubmoduleAddCommand对象需要知道两件事,第一是子模块从哪里克隆而来,第二是它应该存放在哪里。URI属性表示仓库库的克隆地址,这个克隆地址将会传递给clone命令。path属性则指定了相对于parent仓库根工作目录的路径,子模块将被存放在这个路径。这个指令执行之后,parent仓库的工作目录将会变成这样:library仓库存放在modules/library目录下,而且它的工作目录树被检出。call()方法返回一个Repository对象,你可以把它当做一个常规的仓库来使用。这也意味着,你必须在程序中明确显式地关闭返回的仓库,以避免文件句柄泄露。从上图我们可以看到,SubmoduleAddCommand做了一件事,它在parent仓库的根工作目录下创建了一个.git模块文件,并把它添加到索引中。123[submodule "modules/library"]path = modules/libraryurl = git@example.com:path/to/lib.git如果你打开过Git的配置文件,你会发现以上句法。这个文件列出了当前仓库的所有子模块。对于每个模块,文件中列出了它仓库URL地址以及本地路径。一旦commit并push了这个文件,克隆这个仓库的一方就知道哪里可以获取相应的子模块(稍后会详细讲解)。列出子模块当我们添加了一个子模块之后,我们可以会想知道,它是否对于父仓库来说是可知的。第一项测试中我们做了一个基础的检测,验证了某些文件和目录的存在。我们也可以使用一个API来列出一个仓库的子模块,如下所示:1234567891011@Testpublic void testListSubmodules() throws Exception {addLibrarySubmodule();Map submodules= parent.submoduleStatus().call();assertEquals( 1, submodules.size() );SubmoduleStatus status = submodules.get( "modules/library" );assertEquals( INITIALIZED, status.getType() );}SubmoduleStatus命令返回了一个子模块的Map集合,其中键是子模块的路径,值是这个模块的状态值。通过以上代码我们能够验证子模块确实已经添加进去,而且它的状态是INITIALIZED的。这个命令还允许添加一个或多个路径来限制子模块状态。说到状态,JGit的StatusCommand并非原生的Git指令。如果在执行指令时添加选项‐‐ignore-submodules=dirty,那么所有对子模块工作目录的修改都会被忽略。更新子模块子模块通常指向他们所在的仓库的一次特殊的提交。如果之后有人克隆了父仓库,他们也会获得与之完全相同的子模块状态,即便子模块的上游有新的提交。为了修改子模块,你像一下代码一样明确地对其进行更新:1234567891011121314@Testpublic void testUpdateSubmodule() throws Exception {addLibrarySubmodule();ObjectId newHead = library.commit().setMessage( "msg" ).call();File workDir = parent.getRepository().getWorkTree();Git libModule = Git.open( new F‌ile( workDir, "modules/library" ) );libModule.pull().call();libModule.close();parent.add().addF‌ilepattern( "modules/library" ).call();parent.commit().setMessage( "Update submodule" ).call();assertEquals( newHead, getSubmoduleHead( "modules/library" ) );}这个较长的代码片段中,首先第一件事就是提交一些东西到library仓库中(第四行),接着将子模块更新到最近的一次提交。为了让这种更新持久化保存下来,子模块必须被提交(第10,11行)。这次提交在子模块的名下(例子中是modules/library)保存了此次更新的commit-id。最后,通常需要将修改push上去,使得他们对其他仓库可用。在父仓库中更新对子模块的修改将上游的提交拉取到父仓库中也会修改子模块的配置。然而子模块本身并不会自动得到更新。SubmoduleUpdateCommand就是用来解决这个问题。使用这个命令并不需要指定其他参数,它会更新所有已注册的子模块。该命令会克隆缺失的子模块并检出其配置中指定的提交。就如其他子模块命令一样,这里也有一个addPath()方法,以保证只更新给定路径下的子模块。克隆一个包含子模块的仓库此时你可能已经掌握一个规律,所有对子模块的操作都是手动的。克隆一个包含子模块配置的仓库并不会默认克隆它的子模块。但是,CloneCommand命令有一个cloneSubmodules的属性,如果设置为true,那么将会克隆所有配置的子模块。从内部看,在对父仓库进行克隆之后,SubmoduleInitCommand和SubmoduleUpdateCommand命令会被递归地执行,并且父仓库的工作目录会被检出。移除一个子模块如果要移除一个子模块,你会希望可以这样写:1git.submoduleRm().setPath( ... ).call();但是很不幸,不管是原生的Git或者JGit都没有提供内置的移除子模块的指令,希望将来会添加这样的指令,在这之前,我们必须手动去移除子模块。如果你滚动到removeSubmodule()方法你会发现这并不是一件复杂的事。首先,各个子模块会从.gitsubmodules和.git/config配置文件中移除。其次,子模块的入口会从索引中被移除。最后,.gitsubmodules文件以及索引的修改会被提交,并且子模块的内容会从工作目录中删除。遍历子模块原生的Git提供了git submodule foreach命令为每个子模块执行一个shell指令。JGit并没有直接支持这样的指令,而是提供了SubmoduleWalk。该类可以用来迭代仓库中子模块。以下示例程序实现了为所有子模块拉取上游的提交。1234567891011121314151617@Testpublic void testSubmoduleWalk() throws Exception {addLibrarySubmodule();int submoduleCount = 0;Repository parentRepository = parent.getRepository();SubmoduleWalk walk = SubmoduleWalk.forIndex( parentRepository );while( walk.next() ) {Repository submoduleRepository = walk.getRepository();Git.wrap( submoduleRepository ).fetch().call();submoduleRepository.close();submoduleCount++;}walk.release();assertEquals( 1, submoduleCount );}通过next()方法walk对象可以指向下一个子模块,如果没有更多的子模块,该方法会返回false。使用SubmoduleWalk时,通过调用release()方法可以释放子模块相关的资源。再次强调,如果你获得一个子模块的仓库实例可别忘了关闭它。SubmoduleWalk也可以用来获取子模块的详细信息。通过它的大部分getter方法可以访问到当前子模块的属性,诸如path,head,remote URL等等。同步远程URL从上面我们知道子模块的配置保存在父仓库根工作目录下的.gitsubmodules文件中。而至少,在.git/config文件中,我们可以重写覆盖子模块的远程URL。对于每个子模块,它们本身都有一个配置文件。那么反过来,每个子模块可以有另一个远程URL。SubmoduleSyncCommand命令可以用来将所有远程URL重置为.gitmodules中的配置。综上所述,JGit对子模块的支持几乎与原生的Git一致。大部分Git指令都在JGit中实现了,或可以通过一些途径进行仿真。如果你发现一些操作缺失或实现不了,可以去友好且帮得上忙的JGit社区去寻求帮助www.zgxue.com防采集请勿采集本网。

今天遇到了一个git submodule update获取不到最新代码的问题,闹了半天原来是自己对git submodule理解不到位引起的。解决了后,感觉虽然没有什么高深的地方,但是不清楚的时候还是需要费时间去查找问题,所以还是在此记录如下。

Git常用操作命令收集: 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库:$ git remote -v 添加远程仓库:$ git remote add [name] [url] 删除远程仓库:$ git remote rm [name] 修改远程仓库:$ g

1.问题描述

git 的 submodule 方式不会向仓库添加实际的的内容的,只会通过 .gitmodules 文件保留相应的子模块的哈希值。 由于你要真正要用的代码处于一个子目录中,我的方案是你先把这个子目录提取成一个单独的仓库(可以使用 git-subtree.sh 这个脚本),

同事在共同使用的一个工程里修改了代码,这个工程在我本地的工程中是作为submodule来使用的,但是我在本地执行以下命令却获取不到最新提交的代码。

对于一个较大的Git工程,你可能会想在多个仓库之间共享代码,不管这些代码是在多个不同产品间使用的项目共享库或是一些模板。Git通过子模块来实现这样的需求。子模块允许将其他代码仓库的克隆作为子目录放到一个父仓库(有时候也称为父项目)中。

git submodule update --init --recursive

2.问题原因

git submodule在工程中维护了一个文件.gitmodules文件,里边记录了子工程在当前父工程下的存放路径path和子工程的git路径url。同时,在父工程下的.git目录中,还有个modules子目录如下所示。

在这个modules中存放的就是父工程相关的子工程的路径。进入子工程后,可以看到里边有个叫做FETCH_HEAD的文件:

查看该文件的内容如下:

zhuwsh@zhuwsh-TM1705:~/work_space/autonomousDriving/.git/modules/src/utils/dw_xxx_center$ cat FETCH_HEAD

31ecb3458596f22134588460eefb9efa4bd6df23 branch 'master' of https://gitlab.xxx.com/xxx/dw_xxx_center

此时可以发现,这里的commit id和git上最新提交的commitid不一样,这里的commit id还是之前某一次的提交id。

这个其实要说明的是,git submodule update获取代码的时候是和子工程的git路径和这里的commit id有关联的,获取的就是对应的git路径下截止这个commit id的所有代码,之后的代码是不会获取到的。

明白了这个原理后,就知道怎么来修改了。

3.解决方法

既然git远端服务器代码已经修改过了,那么本地每次执行了git submodule update --init --recursive命令后自然需要在自工程对应的路径下执行git pull命令,执行完后服务器端的最新代码就更新到本地了。这个操作做完后再执行git submodule update命令,此时就可以看到上边说的FETCH_HEAD文件中的commit id发生了变化,已经变为当前最新的commit id了。

zhuwsh@zhuwsh-TM1705:~/work_space/autonomousDriving/.git/modules/src/utils/dw_xxx_center$ cat FETCH_HEAD

ab214ead574d51755f4faabad4045de6486b49c2 branch 'master' of https://gitlab.xxx.com/xxx/dw_xxx_center

总结一下就是,在使用git submodule update --init --recursive获取了自工程代码后,还需要执行下面两条命令:

git pullgit submodule update

到此这篇关于详解git submodule update获取不到最新提交的代码的文章就介绍到这了,更多相关git submodule update最新提交内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网!

d:\Program Files (x86)\Git/libexec/git-core\git-pull:line 268:/bin/tr:Bad file numberYour configuration specifies to merge with the ref 'master' 是不是你的代2113码有未提交的更新呀?你修改文件5261后如果没有提交push,那么你4102在pull的时候就会报错的,会让你1653先提交或者merge合并文件【拓展资料】git pull origin 拉取代码到本地,解决拉取代码时发生的文件冲突:1)拉取(下载)指定分支代码合并到当前分支:相当于指定分支的代码与当前分支的代码合并到了一起。命令:git pull origin分支名称注意:每次使用该命令前,需要保证本地工作区是没有任何修改代码的,也就是说需要将本地工作区编辑过的文件添加到暂存区(git add .),或提交到本地仓库中(git commit),才可以使用该命令拉取指定分支的代码合并到当前分支中。每次在操作完git commit命令后,必须拉取一下master分支代码,保持本地正在开发功能逻辑的代码分支代码是最新的,避免后续在提交时冲突过多或覆盖掉其他人的代码的问题出现。如果我们需要将master主干分支的代码拉取并与我们当前分支(xuzhangzheng2)的代码进行合并的话,可以使用该命令。效果如图:执行命令后,可以看到提示Alreadyup-to-date,意思为:已经是最新的了,无需进行更新。当我们拉取的主干分支master被修改后,再执行拉取命令,会看到如图所示效果:粉色框框选部分为自动合并代码的文件绿色框框选部分为本次更新(包含新增、删除、修改)的文件及具体信息,文件名后面的9 表示有9行有更新, +++++++++表示这些更新是新增(+)还是删除(-)。红色框框选部分为本次更新影响的文件数,新增的行数(insertions),删除的行数(deletions)。2)解决拉取代码时发生冲突的情况当我们执行git pullorigin 分支名称 命令想要拉取某一个分支的最新代码到本地,并合并到当前分支时,遇到了如下图的提示:从图中我们看到,出现了两行提示语:CONFLICT(content):Merge conflict inxxxx/xxx/xxx/xxx.javaAutomatic merge failed;fix conflicts andthen commit the result.分别使用红色和绿色框选出来了。红色框框选部分为出现冲突的文件,绿色框框选部分为提示语:自动合并失败,修改冲突然后提交修改后的结果。第一句中提到了一个关键词CONFLICT(content),这个词的出现表明某一个具体文件在合并过程中发生了冲突。发生冲突的原因大致可以理解为你与你的同事两个人在同一个文件中都进行了编辑操作,当其中一个人拉取合并了另一个人的分支,或拉取合并了另一个人合并过的分支的话,就会出现合并冲突的问题。冲突,简单的说,同一个文件2个人编辑,2个人如果编辑的行数没有重合的话(一个人写1-10行,另一个人写11-20行),合并时就没有冲突;若2个人编辑的行数有重合的话(一个人写1-10行,另一个人写5-15行),合并时就会出现冲突,同时,会将2个人编写的内容都罗列出来,让出现冲突的那个人进行解决,最终将冲突解决完毕后,再进行提交合并等操作。此时我们查看出现冲突的文件:按照冲突提示的路径找到冲突对应文件(我使用的IDEA,由于有语法检查,所以一打开就看到错误文件在哪了),打开文件后,会看到如图红框框选部分,被蓝色线分割为了2部分,同时可以看到3个蓝色框框选的文本信息,如下三句:中间的======是用于分割本地变更和远程仓库中的变更的,也就是说出现冲突时,如图,使用======把冲突的部分分割成2块。上面的是本地修改变更的内容,以<<<<<<<HEAD开头。下面的是远程仓库修改变更的内容,以>>>>>>>版本号 结尾。版本号,也就是示例中的a5d8ca0b4fd8847b2c21d96900ac1edcf859ca1b,即为提交的版本号,使用该版本号可以在gitlab中找到提交记录,从而方便查询其他同事在对同文件进行修改时,都修改了哪些内容,便于进解决冲突。解决方法:根据实际业务场景,将本地修改变更的部分和远程仓库中修改变更的部分进行合并,留下满足业务逻辑的代码即可(若团队开发期间,出现冲突时,建议找到相关同事进行沟通,确保自己解决冲突的方法不会影响到其他人编写的功能),同时将上面提到的冲突标识删除掉,不然无法通过语法检查和编译。同时建议使用全文件内容搜索<<<<<<<或======或>>>>>>>,将所有有冲突的地方一一进行解决,保重提交的代码是可运行,没有问题的。解决冲突后,若需要提交代码的话,需先将代码使用git add .存入缓存区,或直接使用git commit –am “本次提交描述” 或git commit –a –m “本次提交描述”将代码提交至本地仓库区,同时再次拉取制定分支的最新代码,确保本次的代码时刻都是最新的,再进行接下来的推送代码至远程仓库操作,注意到你这一行日志2113:libexec/git-core/git-sh-setup: line 83: /bin/sed: Bad file number我看是缺少sed可执行5261程序,或者sed不在这个路径4102下。sed是个行编辑器,可以用1653来批量替换啥的。如果真是这个导致的,安一个sed就行了。此外还有一个:/bin/tr您是在windows下通过什么环境使用git的? windows往往都没有sed tr这些工具。更多追问追答追问兄弟用的这个东西TortoiseGit 来操作。Git-1.9.4-preview20140815.exe TortoiseGit-1.8.9.0-64bit。以前好好的,今天突然成这样了sed tr 是不是我安装这样的软件就可以了?追答那不应该的,这俩软件不需要额外安东西的。尝试重安一下git preview那个,我记得它安了个linux模拟器,带一些命令行工具。追问git preview 刚刚也重装了,还安装一个新版本。还是那样。真晕了!本回答被提问者和网友采纳内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • git submodule管理项目子模块的使用
  • 详解git submodule使用以及注意事项
  • git中submodule子模块的添加、使用和删除的示例代码
  • git submodule使用完整教程(小结)
  • ie 打开服务器下的mht文件的实现方法
  • 详细介绍http cookie
  • 一张图告诉你计算机编程语言的发展历史
  • ue、ui、ucd、interaction design、ued、ux、hci、usability,ia
  • 网址(url)支持的最大长度是多少?最大支持多少个字符?
  • 使用curl命令行模拟登录wordpress的方法
  • 程序员鼓励师插件rainbow fart(彩虹屁)
  • window下安装jdk1.8+tomcat9.0.27+mysql5.7.28的教程图解
  • iisschlp.wsc [88,25] 属性值无效 : progid
  • win10环境下使用hyper-v进行虚拟机创建的教程(图解)
  • git 在使用拉取、推送(pull或push)时时候会出现...
  • 如何添加一个git repo作为自身的一个模块
  • 关于Ubuntu虚机内git submodule的问题
  • 如何将Git子模块更新为最新的原始提交
  • Git怎么推送本地分支到远程新分支上面去
  • 哪里执行git submodule update
  • 如何用jgit管理git子模块
  • 如何用 JGit 管理 Git 子模块
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全javascriptasp.netphp编程ajax相关正则表达式asp编程jsp编程编程10000问css/htmlflex脚本加解密web2.0xml/rss网页编辑器相关技巧安全相关网页播放器其它综合dart首页git submodule管理项目子模块的使用详解git submodule使用以及注意事项git中submodule子模块的添加、使用和删除的示例代码git submodule使用完整教程(小结)ie 打开服务器下的mht文件的实现方法详细介绍http cookie一张图告诉你计算机编程语言的发展历史ue、ui、ucd、interaction design、ued、ux、hci、usability,ia网址(url)支持的最大长度是多少?最大支持多少个字符?使用curl命令行模拟登录wordpress的方法程序员鼓励师插件rainbow fart(彩虹屁)window下安装jdk1.8+tomcat9.0.27+mysql5.7.28的教程图解iisschlp.wsc [88,25] 属性值无效 : progidwin10环境下使用hyper-v进行虚拟机创建的教程(图解)最新idea2020注册码永久激活(激活intellij idea2020永久破解,亲测intellij idea激活码获取方法(i删除svn三种方法delsvn(windows+c/s和b/s两种架构的概念、区别和网址(url)支持的最大长度是多少intellij idea 2020最新注册码(亲5个linux平台程序员最爱的开发工url中斜杠/和反斜杠\的区别小结hadoop 文件系统命令行基础详解解释执行和编译执行的区别?thymeleaf实现th:each双重多重嵌套功能人人都能看懂的 6 种限流实现方案(纯干货基于laravel + vue + element 实现 人力资php和java的主要区别有哪些?哪个最适合w每个程序员需掌握的20个代码命名小贴士asp php 清空access mysql mssql数据库的一个30多年编程经验的程序员总结分享下get和post的真正区别
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved