Как слить два разных репозитория git? [Дубликат]

Похоже, что pip сделал рефакторинг и переместил main на внутренний. Существует всестороннее обсуждение этого вопроса: https://github.com/pypa/pip/issues/5240

Обходной путь для меня состоял в том, чтобы изменить

import pip
pip.main(...)

to

from pip._internal import main
main(...)

Я рекомендую прочитать обсуждение, я не уверен, что это лучший подход, но он работал для моих целей.

1233
задан static_rtti 17 February 2016 в 21:38
поделиться

20 ответов

Единственная ветвь другого репозитория может быть легко помещена под подкаталог, сохраняющий свою историю. Например:

git subtree add --prefix=rails git://github.com/rails/rails.git master

Это будет отображаться как одно комманда, где все файлы главной ветки Rails добавляются в каталог «rails». Однако заголовок commit содержит ссылку на старое дерево истории:

Добавить 'rails /' из commit <rev>

Где <rev> является SHA-1 фиксирует хэш. Вы все еще можете увидеть историю, вините некоторые изменения.

git log <rev>
git blame <rev> -- README.md

Обратите внимание, что вы не можете видеть префикс каталога отсюда, так как это фактическая старая ветка остается нетронутой. Вы должны рассматривать это как обычную фиксацию движения файла: вам понадобится дополнительный прыжок при достижении его.

# finishes with all files added at once commit
git log rails/README.md

# then continue from original tree
git log <rev> -- README.md

. Существуют более сложные решения, такие как выполнение этого вручную или переписывание истории, как описано в других ответах.

Команда git-subtree является частью официального git-contrib, некоторые менеджеры пакетов устанавливают его по умолчанию (OS X Homebrew). Но вам, возможно, придется установить его самостоятельно в дополнение к git.

327
ответ дан Simon Perepelitsa 28 August 2018 в 07:28
поделиться

Вот два возможных решения:

Субмодули

Либо копировать репозиторий A в отдельный каталог в более крупном проекте B, либо (возможно, лучше) клонировать репозиторий A в подкаталог в проекте B. Затем используйте git submodule , чтобы сделать этот репозиторий субмодулем репозитория B.

Это хорошее решение для слабосвязанных репозиториев, где разработка в репозитории A продолжается, и основная часть разработки - отдельная автономная разработка в A. См. также SubmoduleSupport и GitSubmoduleTutorial страницы в Git Wiki.

Subtree merge

Вы можете объединить репозиторий A в подкаталог проекта B, используя стратегию слияния поддерева . Это описано в Subtree Merging и You Markus Prinz.

git remote add -f Bproject /path/to/B
git merge -s ours --allow-unrelated-histories --no-commit Bproject/master
git read-tree --prefix=dir-B/ -u Bproject/master
git commit -m "Merge B project as our subdirectory"
git pull -s subtree Bproject master

(Для Git> = 2.9.0 требуется опция --allow-unrelated-histories.)

Или вы можете использовать инструмент поддерева git ( репозиторий на GitHub ) от apenwarr (Avery Pennarun), анонсированный, например, в его сообщении в блоге . Новая альтернатива подмодулям Git: git subtree .


Я думаю, что в вашем случае (A должен быть частью более крупного проекта B) правильным решением было бы использовать слияние поддерева .

584
ответ дан 11 revs, 10 users 59% 28 August 2018 в 07:28
поделиться

Если вы хотите объединить project-a в project-b:

cd path/to/project-b
git remote add project-a path/to/project-a
git fetch project-a
git merge --allow-unrelated-histories project-a/master # or whichever branch you want to merge
git remote remove project-a

Взято из: git слить разные репозитории?

Этот метод работал очень хорошо для меня, он короче и, на мой взгляд, намного чище.

Примечание: Параметр --allow-unrelated-histories существует только с git> = 2.9. См. Git-git merge Документация / -allow-unrelated-history

1304
ответ дан Andresch Serj 28 August 2018 в 07:28
поделиться

Эта функция будет клонировать удаленное репо в локальный репозиторий, после того, как слияние всех коммитов будет сохранено, git log будет показывать оригинальные коммиты и правильные пути:

function git-add-repo
{
    repo="$1"
    dir="$(echo "$2" | sed 's/\/$//')"
    path="$(pwd)"

    tmp="$(mktemp -d)"
    remote="$(echo "$tmp" | sed 's/\///g'| sed 's/\./_/g')"

    git clone "$repo" "$tmp"
    cd "$tmp"

    git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

    cd "$path"
    git remote add -f "$remote" "file://$tmp/.git"
    git pull "$remote/master"
    git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
    git remote remove "$remote"
    rm -rf "$tmp"
}

Как использовать:

cd current/package
git-add-repo https://github.com/example/example dir/to/save

Если вы делаете небольшие изменения, вы даже можете перемещать файлы / директории объединенного репо на разные пути, например:

repo="https://github.com/example/example"
path="$(pwd)"

tmp="$(mktemp -d)"
remote="$(echo "$tmp" | sed 's/\///g' | sed 's/\./_/g')"

git clone "$repo" "$tmp"
cd "$tmp"

GIT_ADD_STORED=""

function git-mv-store
{
    from="$(echo "$1" | sed 's/\./\\./')"
    to="$(echo "$2" | sed 's/\./\\./')"

    GIT_ADD_STORED+='s,\t'"$from"',\t'"$to"',;'
}

# NOTICE! This paths used for example! Use yours instead!
git-mv-store 'public/index.php' 'public/admin.php'
git-mv-store 'public/data' 'public/x/_data'
git-mv-store 'public/.htaccess' '.htaccess'
git-mv-store 'core/config' 'config/config'
git-mv-store 'core/defines.php' 'defines/defines.php'
git-mv-store 'README.md' 'doc/README.md'
git-mv-store '.gitignore' 'unneeded/.gitignore'

git filter-branch --index-filter '
    git ls-files -s |
    sed "'"$GIT_ADD_STORED"'" |
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
' HEAD

GIT_ADD_STORED=""

cd "$path"
git remote add -f "$remote" "file://$tmp/.git"
git pull "$remote/master"
git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
git remote remove "$remote"
rm -rf "$tmp"

Примечания Пути заменяются через sed, поэтому убедитесь, что он перемещается по надлежащим путям после слияния. Параметр --allow-unrelated-histories существует только тогда, когда git> = 2.9.

0
ответ дан Andrey Izman 28 August 2018 в 07:28
поделиться

Я продолжал проигрывать историю при использовании слияния, поэтому в итоге я использовал rebase, поскольку в моем случае два репозитория достаточно различны, чтобы не сливаться при каждой фиксации:

git clone git@gitorious/projA.git projA
git clone git@gitorious/projB.git projB

cd projB
git remote add projA ../projA/
git fetch projA 
git rebase projA/master HEAD

=> разрешить конфликты , затем продолжайте столько раз, сколько необходимо ...

git rebase --continue

Выполнение этого приводит к одному проекту, все из которого совершаются с projA, за которым следуют коммиты из projB

21
ответ дан Calahad 28 August 2018 в 07:28
поделиться

Я объединять проекты немного вручную, что позволяет мне избежать необходимости иметь дело с конфликтами слияния.

сначала скопировать файлы из другого проекта, но вы хотите их.

cp -R myotherproject newdirectory
git add newdirectory

next pull in history

git fetch path_or_url_to_other_repo

tell git, чтобы объединиться в истории последней извлеченной вещи

echo 'FETCH_HEAD' > .git/MERGE_HEAD

теперь зафиксировать, однако вы обычно совершаете

git commit
0
ответ дан Collin Anderson 28 August 2018 в 07:28
поделиться

Если вы пытаетесь просто склеить два репозитория вместе, подмодули и слияния поддеревьев являются неправильным инструментом для использования, потому что они не сохраняют всю историю файлов (как люди отметили другие ответы). См. Этот ответ здесь для простого и правильного способа сделать это.

13
ответ дан Community 28 August 2018 в 07:28
поделиться

git-subtree хорош, но, вероятно, это не тот, который вам нужен.

Например, если projectA является каталогом, созданным в B, после git subtree,

git log projectA

перечисляет только одно сообщение: слияние. Коммиты из объединенного проекта предназначены для разных путей, поэтому они не отображаются.

Ответ Greg Hewgill близок, хотя на самом деле он не говорит, как переписать пути.

< hr>

Решение на удивление просто.

(1) В A,

PREFIX=projectA #adjust this

git filter-branch --index-filter '
    git ls-files -s |
    sed "s,\t,&'"$PREFIX"'/," |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
    mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' HEAD

Примечание: Это перезаписывает историю, поэтому, если вы намереваетесь продолжать использовать это репо A, вы можете сначала клонировать (копировать) его исходную копию.

(2) Затем в B запустите

git pull path/to/A

Voila! У вас есть каталог projectA в B. Если вы запустите git log projectA, вы увидите все коммиты с A.


В моем случае мне нужны два подкаталога: projectA и projectB. В этом случае я также сделал шаг (1) на B.

62
ответ дан Cœur 28 August 2018 в 07:28
поделиться

У меня была аналогичная задача, но в моем случае мы разработали одну версию кодовой базы в репо A, а затем клонировали ее в новый репо-репо B для новой версии продукта. После исправления некоторых ошибок в репо A нам нужно было FI внести изменения в репо B. Закончилось выполнение следующего:

  1. Добавление удаленного репо B, указывающего на репо A (git remote add. ..)
  2. Вытягивание текущей ветви (мы не использовали мастер для исправлений ошибок) (git pull remoteForRepoA bugFixBranch)
  3. Нажатие сливается в github

Работала с удовольствием :)

4
ответ дан David Lemphers 28 August 2018 в 07:28
поделиться

Данная команда - наилучшее возможное решение, которое я предлагаю.

git subtree add --prefix=MY_PROJECT git://github.com/project/my_project.git master
0
ответ дан eirenaios 28 August 2018 в 07:28
поделиться

Если вы хотите поместить файлы из ветки в репо B в поддереве репо A и , также сохраните историю, продолжайте чтение. (В приведенном ниже примере я предполагаю, что мы хотим, чтобы главная ветвь репо B была объединена с главной ветвью репо A.)

В репо A сначала сделайте следующее, чтобы сделать репо B доступным:

git remote add B ../B # Add repo B as a new remote.
git fetch B

Теперь мы создаем совершенно новую ветвь (только с одной фиксацией) в репо А, которую мы называем new_b_root. Результирующая фиксация будет иметь файлы, которые были зафиксированы в первой фиксации главной ветви репо B, но помещены в подкаталог под названием path/to/b-files/.

git checkout --orphan new_b_root master
git rm -rf . # Remove all files.
git cherry-pick -n `git rev-list --max-parents=0 B/master`
mkdir -p path/to/b-files
git mv README path/to/b-files/
git commit --date="$(git log --format='%ai' $(git rev-list --max-parents=0 B/master))"

Объяснение: Параметр --orphan для команды проверки проверяет файлы из главной ветви А, но не создает никаких фиксаций. Мы могли бы выбрать любую фиксацию, потому что в дальнейшем мы все равно очищаем все файлы. Затем, не совершая пока (-n), мы выбираем первую фиксацию из главной ветви B. (Вишневый диск сохраняет исходное сообщение фиксации, которое, как представляется, не делает прямую проверку). Затем мы создаем поддерево, где мы хотим поместить все файлы из репо B. Затем нам нужно переместить все файлы, которые были введены в вишневый выбор в поддерево. В приведенном выше примере есть только файл README для перемещения. Затем мы фиксируем фиксацию корня B-repo и в то же время сохраняем временную метку исходного коммита.

Теперь мы создадим новую ветвь B/master поверх вновь созданный new_b_root. Мы называем новую ветвь b:

git checkout -b b B/master
git rebase -s recursive -Xsubtree=path/to/b-files/ new_b_root

Теперь мы объединяем ветвь b в A/master:

git checkout master
git merge --allow-unrelated-histories --no-commit b
git commit -m 'Merge repo B into repo A.'

Наконец, вы можете удалить B удаленные и временные ветви:

git remote remove B
git branch -D new_b_root b

Окончательный график будет иметь такую ​​структуру:

5
ответ дан Finn Haakansson 28 August 2018 в 07:28
поделиться

Подмодульный подход хорош, если вы хотите поддерживать проект отдельно. Тем не менее, если вы действительно хотите объединить оба проекта в один и тот же репозиторий, вам придется немного поработать.

Первое, что нужно было бы использовать git filter-branch, чтобы переписать имена всего в второй репозиторий находится в подкаталоге, где вы хотели бы, чтобы они закончили. Таким образом, вместо foo.c, bar.html, у вас будут projb/foo.c и projb/bar.html.

Затем вы можете сделать что-то вроде следующего:

git remote add projb [wherever]
git pull projb

git pull выполнит git fetch, а затем git merge. Не должно быть конфликтов, если репозиторий, к которому вы тянете, еще не имеет директорию projb/.

Дальнейший поиск указывает, что что-то подобное было сделано для объединения gitk в git. Джунио С Хамано пишет об этом здесь: http://www.mail-archive.com/git@vger.kernel.org/msg03395.html

188
ответ дан Greg Hewgill 28 August 2018 в 07:28
поделиться

Я знаю, что это уже давно, но я не был доволен другими ответами, которые я нашел здесь, поэтому я написал это:

me=$(basename $0)

TMP=$(mktemp -d /tmp/$me.XXXXXXXX)
echo 
echo "building new repo in $TMP"
echo
sleep 1

set -e

cd $TMP
mkdir new-repo
cd new-repo
    git init
    cd ..

x=0
while [ -n "$1" ]; do
    repo="$1"; shift
    git clone "$repo"
    dirname=$(basename $repo | sed -e 's/\s/-/g')
    if [[ $dirname =~ ^git:.*\.git$ ]]; then
        dirname=$(echo $dirname | sed s/.git$//)
    fi

    cd $dirname
        git remote rm origin
        git filter-branch --tree-filter \
            "(mkdir -p $dirname; find . -maxdepth 1 ! -name . ! -name .git ! -name $dirname -exec mv {} $dirname/ \;)"
        cd ..

    cd new-repo
        git pull --no-commit ../$dirname
        [ $x -gt 0 ] && git commit -m "merge made by $me"
        cd ..

    x=$(( x + 1 ))
done
6
ответ дан jettero 28 August 2018 в 07:28
поделиться

Объединение 2 репозиториев

git clone ssh://<project-repo> project1
cd project1
git remote add -f project2 project2
git merge --allow-unrelated-histories project2/master
git remote rm project2

delete the ref to avoid errors
git update-ref -d refs/remotes/project2/master
3
ответ дан Koopakiller 28 August 2018 в 07:28
поделиться

Если вы хотите объединить три или более проектов в одном коммите, выполните действия, описанные в других ответах (remote add -f, merge). Затем (мягкий) сбросьте индекс на старую голову (где не произошло слияния). Добавьте все файлы (git add -A) и скопируйте их (сообщение «Объединение проектов A, B, C и D в один проект). Теперь это идентификатор commit.

Теперь создайте .git/info/grafts со следующим содержимым:

<commit-id of master> <list of commit ids of all parents>

Запустить git filter-branch -- head^..head head^2..head head^3..head. Если у вас более трех ветвей, просто добавьте столько же head^n..head, сколько у вас есть ветви. Чтобы обновить теги, добавьте --tag-name-filter cat. Не всегда добавляйте это, потому что это может привести к перезаписи некоторых коммитов. Подробнее см. В странице man filter-branch , найдите «трансплантаты».

Теперь, ваш последний commit имеет соответствующих родителей.

3
ответ дан koppor 28 August 2018 в 07:28
поделиться

Я собрал много информации здесь о Stack & nbsp; OverFlow и т. д., и мне удалось собрать сценарий вместе, который решает проблему для меня.

Оговорка в том, что она учитывает только «развить» ветвь каждого репозитория и слить его в отдельный каталог в совершенно новом репозитории.

Теги и другие ветви игнорируются - это может быть не то, что вы хотите.

Скрипт даже обрабатывает ветки и теги функций - переименование их в новом проекте, чтобы вы знали, откуда они пришли.

#!/bin/bash
#
################################################################################
## Script to merge multiple git repositories into a new repository
## - The new repository will contain a folder for every merged repository
## - The script adds remotes for every project and then merges in every branch
##   and tag. These are renamed to have the origin project name as a prefix
##
## Usage: mergeGitRepositories.sh <new_project> <my_repo_urls.lst>
## - where <new_project> is the name of the new project to create
## - and <my_repo_urls.lst> is a file containing the URLs to the repositories
##   which are to be merged on separate lines.
##
## Author: Robert von Burg
##            eitch@eitchnet.ch
##
## Version: 0.2.0
## Created: 2015-06-17
##
################################################################################
#

# Disallow using undefined variables
shopt -s -o nounset

# Script variables
declare SCRIPT_NAME="${0##*/}"
declare SCRIPT_DIR="$(cd ${0%/*} ; pwd)"
declare ROOT_DIR="$PWD"


# Detect proper usage
if [ "$#" -ne "2" ] ; then
  echo -e "ERROR: Usage: $0 <new_project> <my_repo_urls.lst>"
  exit 1
fi


# Script functions
function failed() {
  echo -e "ERROR: Merging of projects failed:"
  echo -e "$1"
  exit 1
}

function commit_merge() {
  current_branch="$(git symbolic-ref HEAD 2>/dev/null)"
  CHANGES=$(git status | grep "working directory clean")
  MERGING=$(git status | grep "merging")
  if [[ "$CHANGES" != "" ]] && [[ "$MERGING" == "" ]] ; then
    echo -e "INFO:   No commit required."
  else
    echo -e "INFO:   Committing ${sub_project}..."
    if ! git commit --quiet -m "[Project] Merged branch '$1' of ${sub_project}" ; then
      failed "Failed to commit merge of branch '$1' of ${sub_project} into ${current_branch}"
    fi
  fi
}


## Script variables
PROJECT_NAME="${1}"
PROJECT_PATH="${ROOT_DIR}/${PROJECT_NAME}"
REPO_FILE="${2}"
REPO_URL_FILE="${ROOT_DIR}/${REPO_FILE}"


# Make sure the REPO_URL_FILE exists
if [ ! -e "${REPO_URL_FILE}" ] ; then
  echo -e "ERROR: Repo file ${REPO_URL_FILE} does not exist!"
  exit 1
fi


# Make sure the required directories don't exist
if [ -e "${PROJECT_PATH}" ] ; then
  echo -e "ERROR: Project ${PROJECT_NAME} already exists!"
  exit 1
fi


# Create the new project
echo -e "INFO: Creating new git repository ${PROJECT_NAME}..."
echo -e "===================================================="
cd ${ROOT_DIR}
mkdir ${PROJECT_NAME}
cd ${PROJECT_NAME}
git init
echo "Initial Commit" > initial_commit

# Since this is a new repository we need to have at least one commit
# thus were we create temporary file, but we delete it again.
# Deleting it guarantees we don't have conflicts later when merging
git add initial_commit
git commit --quiet -m "[Project] Initial Master Repo Commit"
git rm --quiet initial_commit
git commit --quiet -m "[Project] Initial Master Repo Commit"
echo


# Merge all projects into th branches of this project
echo -e "INFO: Merging projects into new repository..."
echo -e "===================================================="
for url in $(cat ${REPO_URL_FILE}) ; do

  # Extract the name of this project
  export sub_project=${url##*/}
  sub_project=${sub_project%*.git}

  echo -e "INFO: Project ${sub_project}"
  echo -e "----------------------------------------------------"

  # Fetch the project
  echo -e "INFO:   Fetching ${sub_project}..."
  git remote add "${sub_project}" "${url}"
  if ! git fetch --no-tags --quiet ${sub_project} 2>/dev/null ; then
    failed "Failed to fetch project ${sub_project}"
  fi

  # Add remote branches
  echo -e "INFO:   Creating local branches for ${sub_project}..."
  while read branch ; do 
    branch_ref=$(echo $branch | tr " " "\t" | cut -f 1)
    branch_name=$(echo $branch | tr " " "\t" | cut -f 2 | cut -d / -f 3-)

    echo -e "INFO:   Creating branch ${branch_name}..."

    # Create and checkout new merge branch off of master
    git checkout --quiet -b "${sub_project}/${branch_name}" master
    git reset --hard --quiet
    git clean -d --force --quiet

    # Merge the project
    echo -e "INFO:   Merging ${sub_project}..."
    if ! git merge --quiet --no-commit "remotes/${sub_project}/${branch_name}" 2>/dev/null ; then
      failed "Failed to merge branch 'remotes/${sub_project}/${branch_name}' from ${sub_project}"
    fi

    # And now see if we need to commit (maybe there was a merge)
    commit_merge "${sub_project}/${branch_name}"

    # Relocate projects files into own directory
    if [ "$(ls)" == "${sub_project}" ] ; then
      echo -e "WARN:   Not moving files in branch ${branch_name} of ${sub_project} as already only one root level."
    else
      echo -e "INFO:   Moving files in branch ${branch_name} of ${sub_project} so we have a single directory..."
      mkdir ${sub_project}
      for f in $(ls -a) ; do
        if  [[ "$f" == "${sub_project}" ]] || 
            [[ "$f" == "." ]] || 
            [[ "$f" == ".." ]] ; then 
          continue
        fi
        git mv -k "$f" "${sub_project}/"
      done

      # Commit the moving
      if ! git commit --quiet -m  "[Project] Move ${sub_project} files into sub directory" ; then
        failed "Failed to commit moving of ${sub_project} files into sub directory"
      fi
    fi
    echo
  done < <(git ls-remote --heads ${sub_project})


  # Checkout master of sub probject
  if ! git checkout "${sub_project}/master" 2>/dev/null ; then
    failed "sub_project ${sub_project} is missing master branch!"
  fi

  # Copy remote tags
  echo -e "INFO:   Copying tags for ${sub_project}..."
  while read tag ; do 
    tag_ref=$(echo $tag | tr " " "\t" | cut -f 1)
    tag_name=$(echo $tag | tr " " "\t" | cut -f 2 | cut -d / -f 3)

    # hack for broken tag names where they are like 1.2.0^{} instead of just 1.2.0
    tag_name="${tag_name%%^*}"

    tag_new_name="${sub_project}/${tag_name}"
    echo -e "INFO:     Copying tag ${tag_name} to ${tag_new_name} for ref ${tag_ref}..."
    if ! git tag "${tag_new_name}" "${tag_ref}" 2>/dev/null ; then
      echo -e "WARN:     Could not copy tag ${tag_name} to ${tag_new_name} for ref ${tag_ref}"
    fi
  done < <(git ls-remote --tags ${sub_project})

  # Remove the remote to the old project
  echo -e "INFO:   Removing remote ${sub_project}..."
  git remote rm ${sub_project}

  echo
done


# Now merge all project master branches into new master
git checkout --quiet master
echo -e "INFO: Merging projects master branches into new repository..."
echo -e "===================================================="
for url in $(cat ${REPO_URL_FILE}) ; do

  # extract the name of this project
  export sub_project=${url##*/}
  sub_project=${sub_project%*.git}

  echo -e "INFO:   Merging ${sub_project}..."
  if ! git merge --quiet --no-commit "${sub_project}/master" 2>/dev/null ; then
    failed "Failed to merge branch ${sub_project}/master into master"
  fi

  # And now see if we need to commit (maybe there was a merge)
  commit_merge "${sub_project}/master"

  echo
done


# Done
cd ${ROOT_DIR}
echo -e "INFO: Done."
echo

exit 0

Вы также можете получить его из http: //paste.ubuntu. com / 11732805

Сначала создайте файл с URL-адресом для каждого репозитория, например:

git@github.com:eitchnet/ch.eitchnet.parent.git
git@github.com:eitchnet/ch.eitchnet.utils.git
git@github.com:eitchnet/ch.eitchnet.privilege.git

Затем вызовите сценарий, в котором указывается имя проекта и путь к скрипту:

./mergeGitRepositories.sh eitchnet_test eitchnet.lst

В самом скрипте есть много комментариев, которые должны объяснить, что он делает.

6
ответ дан Peter Mortensen 28 August 2018 в 07:28
поделиться

Я пытался делать то же самое в течение нескольких дней, я использую git 2.7.2. Subtree не сохраняет историю.

Вы можете использовать этот метод, если вы не будете использовать старый проект еще раз.

Я бы предположил, что сначала вы введете B и работаете в ветке.

Вот шаги без ветвления:

cd B

# You are going to merge A into B, so first move all of B's files into a sub dir
mkdir B

# Move all files to B, till there is nothing in the dir but .git and B
git mv <files> B

git add .

git commit -m "Moving content of project B in preparation for merge from A"


# Now merge A into B
git remote add -f A <A repo url>

git merge A/<branch>

mkdir A

# move all the files into subdir A, excluding .git
git mv <files> A

git commit -m "Moved A into subdir"


# Move B's files back to root    
git mv B/* ./

rm -rf B

git commit -m "Reset B to original state"

git push

Если вы сейчас регистрируете любой из файлов в subdir A, вы получите полную историю

git log --follow A/<file>

Это сообщение, помогите мне сделать это:

http://saintgimp.org/2013/01/22/merging-two-git-repositories-into-one-repository-without-losing-file-history /

8
ответ дан Rian 28 August 2018 в 07:28
поделиться

Если оба репозитория имеют одинаковые файлы (например, два репозитория Rails для разных проектов), вы можете получить данные вторичного репозитория в свой текущий репозиторий:

git fetch git://repository.url/repo.git master:branch_name

, а затем объединить его с текущим репозиторий:

git merge --allow-unrelated-histories branch_name

Если ваша версия Git меньше 2.9, удалите --allow-unrelated-histories.

После этого могут возникнуть конфликты. Вы можете разрешить их, например, с помощью git mergetool. kdiff3 можно использовать исключительно с клавиатурой, поэтому при чтении кода требуется всего 5 файлов конфликтов всего несколько минут.

Не забудьте завершить слияние:

git commit
40
ответ дан Smar 28 August 2018 в 07:28
поделиться

Подобно @Smar, но использует пути файловой системы, заданные в PRIMARY и SECONDARY:

PRIMARY=~/Code/project1
SECONDARY=~/Code/project2
cd $PRIMARY
git remote add test $SECONDARY && git fetch test
git merge test/master

Затем вы вручную объединяетесь.

(адаптировано из сообщения Anar Манафы )

3
ответ дан Turadg 28 August 2018 в 07:28
поделиться

Слить A внутри B:

1) В проекте A

git fast-export --all --date-order > /tmp/ProjectAExport

2) В проекте B

git checkout -b projectA
git fast-import --force < /tmp/ProjectAExport

В эта ветка выполняет все операции, которые вам нужно выполнить и совершать их.

C) Затем вернитесь к мастеру и классическому объединению между двумя ветвями:

git checkout master
git merge projectA
3
ответ дан user123568943685 28 August 2018 в 07:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: