Programing

모든 하위 디렉토리에 대해 git pull을 실행하십시오.

lottogame 2020. 4. 29. 08:07
반응형

모든 하위 디렉토리에 대해 git pull을 실행하십시오.


이 질문에는 이미 답변이 있습니다.

각 리포지토리 cd의 루트 디렉토리에 연결 하지 않고 공유 부모의 디렉토리에서 여러 git 리포지토리를 어떻게 업데이트 할 수 있습니까? 나는 모든 별도의 Git 저장소가 (있는 다음이 없는 서브 모듈) :

/plugins/cms
/plugins/admin
/plugins/chart

한 번에 모두 업데이트하거나 최소한 현재 작업 과정을 단순화하고 싶습니다.

cd ~/plugins/admin
git pull origin master
cd ../chart
git pull

기타


plugins이 경우 상위 디렉토리에서 다음을 실행하십시오 .

find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull origin master \;

명확히하기 위해 :

  • find . 현재 디렉토리를 검색
  • -type d 파일이 아닌 디렉토리를 찾기 위해
  • -depth 1 하나의 하위 디렉토리의 최대 깊이
  • -exec {} \; 모든 찾기에 대해 사용자 정의 명령을 실행합니다
  • git --git-dir={}/.git --work-tree=$PWD/{} pull 자식은 개별 디렉토리를 가져옵니다

find를 가지고 놀기 위해, echo다음 -exec과 같이 미리보기를 사용하는 것이 좋습니다 .

find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;

참고 : -depth 1옵션을 사용할 수 없으면을 시도하십시오 -mindepth 1 -maxdepth 1.


ls | xargs -I{} git -C {} pull

병렬로 수행하려면 다음을 수행하십시오.

ls | xargs -P10 -I{} git -C {} pull

leo의 솔루션보다 기술이 조금 더 낮습니다.

for i in */.git; do ( echo $i; cd $i/..; git pull; ); done

작업 디렉토리의 모든 Git 리포지토리가 업데이트됩니다. 이름을 명시 적으로 나열 할 필요가 없습니다 ( "cms", "admin", "chart"). "cd"명령은 서브 쉘에만 영향을 미칩니다 (괄호를 사용하여 생성).


나는 이것을 사용한다 :

find . -name ".git" -type d | sed 's/\/.git//' |  xargs -P10 -I{} git -C {} pull

범용 : 현재 디렉토리 아래에있는 모든 자식 리포지토리를 업데이트합니다.


실제로 하위 폴더에 자식 저장소가 있는지 여부를 모르는 경우 가장 좋은 방법은 저장소를 find가져 오는 것입니다.

find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \;

PowerShell과 동등한 기능은 다음과 같습니다.

Get-ChildItem -Recurse -Directory -Hidden  -Filter .git | ForEach-Object { & git --git-dir="$($_.FullName)" --work-tree="$(Split-Path $_.FullName -Parent)" pull origin master }

cms, admin 및 chart가 모두 저장소의 일부인 한 자동으로 발생합니다.

문제는 이러한 각 플러그인이 git 하위 모듈이라는 것입니다.

git help submodule자세한 내용을 보려면 실행 하십시오.

편집하다

bash에서 이것을하기 위해 :

cd plugins
for f in cms admin chart
do 
  cd $f && git pull origin master && cd ..
done

mr유틸리티 (일명 myrepos)을 제공하는 뛰어난 바로이 문제에 대한 해결책을. 좋아하는 패키지 관리자를 사용하여 설치하거나 github에서 직접mr 스크립트를 가져 와서 또는 다른 곳에 넣으 십시오 . 그런 다음 이 repos가 공유 하는 상위 폴더에 다음과 유사한 내용 으로 기본 파일을 작성하십시오 (필요에 따라 URL 조정).$HOME/binPATHcdplugins.mrconfig

# File: .mrconfig
[cms]
checkout = git clone 'https://<username>@github.com/<username>/cms' 'cms'

[admin]
checkout = git clone 'https://<username>@github.com/<username>/admin' 'admin'

[chart]
checkout = git clone 'https://<username>@github.com/<username>/chart' 'chart'

After that, you can run mr up from the top level plugins folder to pull updates from each repository. (Note that this will also do the initial clone if the target working copy doesn't yet exist.) Other commands you can execute include mr st, mr push, mr log, mr diff, etc—run mr help to see what's possible. There's a mr run command that acts as a pass-through, allowing you to access VCS commands not directly suported by mr itself (e.g., mr run git tag STAGING_081220015). And you can even create your own custom commands that execute arbitrary bits of shell script targeting all repos!

mr is an extremely useful tool for dealing with multiple repos. Since the plugins folder is in your home directory, you might also be interested in vcsh. Together with mr, it provides a powerful mechanism for managing all of your configuration files. See this blog post by Thomas Ferris Nicolaisen for an overview.


Most compact method, assuming all sub-dirs are git repos:

ls | parallel git -C {} pull

gitfox is a tool to execute command on all subrepos

npm install gitfox -g
g pull

None of the top 5 answers worked for me, and the question talked about directories.

This worked:

for d in *; do pushd $d && git pull && popd; done

My humble construction that

  • shows the current path (using python, convenient and just works, see How to get full path of a file?)
  • looks directly for .git subfolder: low chance to emit a git command in a non-git subfolder
  • gets rid of some warnings of find

as follow:

find . \
    -maxdepth 2 -type d \
    -name ".git" \
    -execdir python -c 'import os; print(os.path.abspath("."))' \; \
    -execdir git pull \;

Of course, you may add other git commands with additional -execdir options to find, displaying the branch for instance:

find . \
    -maxdepth 2 -type d \
    -name ".git" \
    -execdir python -c 'import os; print(os.path.abspath("."))' \; \
    -execdir git branch \;
    -execdir git pull \;

You can try this

find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \;

Also, you can add your customized output by adding one more && argument like.

find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull && git status" \;

Original answer 2010:

If all of those directories are separate git repo, you should reference them as submodules.

That means your "origin" would be that remote repo 'plugins' which only contains references to subrepos 'cms', 'admin', 'chart'.

A git pull followed by a git submodule update would achieve what your are looking for.


Update January 2016:

With Git 2.8 (Q1 2016), you will be able to fetch submodules in parallel (!) with git fetch --recurse-submodules -j2.
See "How to speed up / parallelize downloads of git submodules using git clone --recursive?"


I use this

for dir in $(find . -name ".git")
do cd ${dir%/*}
    echo $PWD
    git pull
    echo ""
    cd - > /dev/null
done

Github


I combined points from several comments and answers:

find . -maxdepth 1 -type d -name .git -execdir git pull \;

If you have a lot of subdirs with git repositories, you can use parallel

ls | parallel -I{} -j100 '
  if [ -d {}/.git ]; then
    echo Pulling {}
    git -C {} pull > /dev/null && echo "pulled" || echo "error :("
  else
     echo {} is not a .git directory
  fi
'

참고URL : https://stackoverflow.com/questions/3497123/run-git-pull-over-all-subdirectories

반응형