2013-06-14 9 views
16

Pracuję z 5 reposami, które sklonowałem w moim środowisku programistycznym. Kiedy chcę zaktualizować repo git, wchodzę do folderu/home/adrian/repo1/a zrobić:Utwórz skrypt powłoki, aby zaktualizować 3 repliki git.

mistrz git checkout git głównego pochodzenie ciągnąć

Ale wtedy, codziennie rano muszę zrobić to samo dla pozostałych 4 repozytoriów. To dość kłopotliwe.

Czy mogę umieścić to w skrypcie powłoki? Mam na myśli, jeśli napiszę te polecenia git w skrypcie powłoki i uruchomię to, czy będę w stanie zaktualizować wszystkie repozytorium?

myślałem o napisaniu czegoś takiego ...

cd repo1 
git checkout master 
git pull origin master 
cd .. 
cd repo2 
git checkout master 
git pull origin master 
cd .. 

(jestem na Linux)

Edit: Może to jest trudniejsze niż myślałem. Najczęściej kiedy robię "git pull origin master", dostaję erorracje takie jak "Twoje lokalne zmiany w .... zostaną nadpisane przez scalenie." Więc muszę wejść do odpowiedniego oddziału i schować rzeczy ..

Edit 2:

Co mam na myśli to robić, jeśli konflikt dzieje, zignorować i przejść do następnego repo

cd repo1 
git checkout master 
git pull origin master 

(if there is conflict, ignore and go to the next line but dont stop here) 

cd .. 
cd repo2 
git checkout master 
git pull origin master 
cd .. 

ale nie wiem jak napisać rzecz w nawiasie.

+0

co, jeśli masz niezatwierdzone zmiany w innym oddziale, gdy próbujesz zapłacić, a jeśli masz konflikty, gdy je wyciągasz? e nie jest niczym złym w zasadzie z tym, co chcesz zrobić, ale musisz zastanowić się, dlaczego twoje polecenia mogą zawieść (i co robić). – bengoesboom

+0

Tak, musiałbym wziąć to pod uwagę. Napisałem to w Edit. Zasadniczo, jeśli pojawi się konflikt, należy go ukryć. Dzieje się tak dlatego, że każdej nocy przed wyjazdem i po zobowiązaniu się do wykonania moich czynności i sprawdzeniu wszystkiego, sprawdzam, czy wszystko jest czyste i aktualne, ale tak, w rzeczywistości wszystko może się zdarzyć rano, a może powinienem gdzieś ukryć ... – ado

+0

Domyślam się, że chcesz utrzymywać śledzenie na odległość każdego dnia, używając 'git' w sposób' svn'. Naprawdę 'git' to dvs, możesz wykonać swoją pracę lokalnie i uruchomić' git pull --rebase' przed push. To pobierze źródło ze zdalnego i zastosuje na nim zmianę, może spowodować konflikt, ale można go rozwiązać. – dyng

Odpowiedz

23

Po pierwsze, I recommend against using git pull. Zamiast tworzyć bezpieczniejsze git up Alias:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}' 

Zobacz this answer o wyjaśnienie git up.

Wtedy można bezpiecznie skrypt to:

#!/bin/sh 
for repo in repo1 repo2 repo3 repo4; do 
    (cd "${repo}" && git checkout master && git up) 
done 
+0

Dzięki! Przekonałaś mnie! nie więcej git pull – ado

+0

Przy okazji należy napisać: ... czy git checkout master (cd "$ {repo}" && git up) .... w pętli? – ado

+0

@adriancdperu: To zależy od twoich preferencji/okoliczności. Jeśli chcesz zaktualizować aktualnie wyrejestrowaną gałąź, to nie; jeśli chcesz zaktualizować tylko 'master', to tak. (Mam ciekawszą wersję tego prostego aliasu "git up", którego używam do aktualizowania wszystkich moich oddziałów naraz.Tak więc, nie muszę nigdy "git checkout" niczego.) –

2

Ponieważ mam wiele git repo wyrejestrowany lokalnie do pracy, postanowiłem napisać bardziej szczegółowy scenariusz, aby zaktualizować wszystkie (skrypt bash repo będzie szukać git repo do 3 foldery głębokich, aby zaktualizować. będzie wtedy zrobić zapas git, przynieś, rebase i zwijanie pop lokalne zmiany z powrotem. scenariusz do mnie biegnie w git powłoki bash na Windows.

#!/bin/bash 
# Usage: 
# ./update_git_repos.sh [parent_directory] 
# example usage: 
#  ./update_git_repos.sh C:/GitProjects/ [MAKE SURE YOU USE/SLASHES] 

updateRepo() { 
    local dir="$1" 
    local original_dir="$2" 
    cd $dir # switch to the git repo 
    repo_url=$(git config --get remote.origin.url) 

    echo "****************************************************************************" 
    echo "Updating Repo: $dir with url: $repo_url" 
    echo "Starting update in $PWD" 

    main_branch="master" 
    if [ "$repo_url" == "[email protected]:repo/repo.git" ]; then # if you have a repo where the primary branch isnt master 
     $main_branch="trunk" 
    fi 

    # update the repo, then stash any local changes 
    echo -e "\ncalling: git fetch --all && git stash" 
    (git fetch --all && git stash) 
    current_branch=$(git rev-parse --abbrev-ref HEAD) 

    # switch to master/trunk branch and rebase it, then switch back to original branch 
    if [ $current_branch != $main_branch ]; then 
     echo -e "\ncalling: git checkout $main_branch && git rebase && git checkout $current_branch" 
     (git checkout $main_branch && git rebase && git checkout $current_branch) 
    fi 

    # rebase the original branch and then stash pop back to original state 
    echo -e "\ncalling: git rebase && git stash pop on branch: $current_branch" 
    (git rebase && git stash pop) 

    #switch back to the starting directory 
    cd $original_dir 
    echo "" 
} 

directory_to_update=${1} 

if [ -z "$directory_to_update" ] ; then 
    echo "no directory passed in, using current directory" 
    directory_to_update=$PWD 
fi 
echo "Updating git repo's in directory: $directory_to_update" 
count=0 
for dir in $(find $directory_to_update -maxdepth 4 -type d -name .git | xargs -n 1 dirname); do 
    updateRepo $dir $directory_to_update #& #uncomment to make it run in multiple threads, meh 
    ((count+=1)) 
done 

echo "$count local git repos have been updated!" 
Powiązane problemy