2017-01-31 2 views
5
for k in $(git branch -r --merged origin/master | cut -d" " -f 3); do 
    echo $k 
done 

У меня есть список проектов git, которые я хочу очистить старые ветви в, что я хочу сделать, это перечислить и удалить все ветви, которые объединены с мастером.Список и удаление ветвей git без клонирования

Есть ли способ сделать это без клонирования каждого репо локально?

+0

использовать 'git branch' и удалить с помощью' git branch -d '. – phunsukwangdu

+0

Я буду использовать 'git branch -d branch_name' для удаления ветки yes, то, что я хочу знать, есть, если есть способ сделать это, не имея локальной копии репозитория –

+0

ссылайтесь на эту ссылку [http: // stackoverflow .com/questions/2003505/how-to-delete-a-git-branch-both-local-and-remote) – phunsukwangdu

ответ

8

git ls-remote Вам нужно:

ИМЯ

git-ls-remote - ссылки Список в удаленном хранилище

СИНТАКСИС

git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>] 
       [-q | --quiet] [--exit-code] [--get-url] 
       [--symref] [<repository> [<refs>...]] 

ОПИСАНИЕ

Отображает ссылки, доступные в удаленном репозитории вместе с связанными идентификаторами фиксации .

Так он работает как:

% git ls-remote origin 
af51dfb080728117d898e1d0a10e3fe01ed67063  HEAD 
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c  refs/heads/expdate-fix 
af51dfb080728117d898e1d0a10e3fe01ed67063  refs/heads/master 
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55  refs/heads/redux 
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522  refs/heads/rest 
7ad17cdf8b0dcd1a29a1795a363279fb3c76ac66  refs/tags/test.key 
be0b2d6881902600fb3d6686c10d0a47f1e6751a  refs/tags/test.pub 

Чтобы получить только ветви (головы), вы должны сузить refspec вниз:

% git ls-remote origin 'refs/heads/*' 
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c  refs/heads/expdate-fix 
af51dfb080728117d898e1d0a10e3fe01ed67063  refs/heads/master 
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55  refs/heads/redux 
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522  refs/heads/rest 

Теперь вы можете написать сценарий вокруг этого выхода, как

git ls-remote origin 'refs/heads/*' | while read sha ref; do 
    # test if $sha is merged 
done 

Чтобы удалить ветку, вам необходимо нажать кнопку nothin г»к нему, как и в

git push origin :refs/heads/feature-x 

(заметить пустую строку слева от„:“, который определял, что подтолкнуть к тому, что находится на правой стороне).

Таким образом, мы получаем что-то вроде

#!/bin/sh 
set -e -u 
git ls-remote origin 'refs/heads/*' | while read sha ref; do 
    # test if $sha is merged 
    E=`git cat-file -t "$sha" 2>&1` 
    test $? -ne 0 -a "${E#*git cat-file: *}" = "could not get object info" && continue 
    git branch --merged "$sha" && printf ':%s\0' "$ref" 
done | xargs -0 git push origin 

Обратите внимание, что мы используем printf оболочки встроенную команду, чтобы разграничить имена выхода рефов мы с ASCII NUL символ, а затем передать -0 в xargs ожидать NUL концевым вход. Таким образом, мы работаем вокруг фанк-ссылок (содержащих пробелы и т. Д.).

Некоторые пояснения:

  • Если git cat-file -t <object_sha1_name> не удается найти объект с указанным именем SHA1 в локальном хранилище, он выходит с ненулевым кодом завершения и печатает

    фатальный: git cat-файл: не удалось получить информацию об объекте

    к своей лестнице р.

  • Так, чтобы проверить, является ли история удаленных точек рефа на существует в локальном хранилища бежит git cat-file -t на имени SHA1 объекта он точки на, возьмите комбинированный вывод этой команды, а затем проверить ли это завершился с кодом ненулевого выхода ($? -ne 0) и указывает, является ли его сообщение об ошибке отсутствующий объект (The ${VAR#PATTERN} удаляет префикс, соответствующий PATTERN из содержимого переменной VAR и возвращает полученное значение).

  • Если история удаленные точки рефа на не существует в локальном хранилище, оно не может быть объединено с любым из местных рефов по определению, так, если мы обнаружим такой реф, мы пропускаем его дальнейшее тестирование с git branch --merged.

+0

Это именно то, что мне нужно, я раньше видел L-пульт, но не понял. Спасибо –

+0

Здесь есть одна большая проблема: если ваш репозиторий не обновляется с этим удаленным, 'git branch -merged' не может дать вам правильные ответы. Это означает, что вы могли бы сначала запустить git fetch, а затем работать локально. – torek

+0

@torek, это правильно. С другой стороны, сам вопрос был направлен на то, чтобы избежать загрузки истории (я принимаю «без клонирования» также означает «без выборки»). В одном случае это будет проверка на специальный случай «commit not in the repository». К сожалению, обработка этого случая в 'git branch {--contains | --merged}' (для меня) удивительна: поскольку они * предполагают * объект с заданным именем существует и вызывают не очень полезное сообщение об ошибке, если это не так. Предположительно, запуск 'git cat-file -t '$ sha" 'на имя фиксации сначала будет лучше, поскольку он ведет себя более предсказуемым образом IMO. – kostix

Смежные вопросы