简体   繁体   中英

How to push a directory from one repository to the master branch of another repository?

I have two repositories. I need to push a directory from one repository to the master branch of the other repository.

My_Working_Dir
  file1
  file2
  Dir1
    file3
    file4

remote_branch/master
   file3
   file4

I like to push the Dir1 directory from the first repository to the master branch on the second repository. Any idea on how to do this?

Thanks a lot in advance.

You don't push directories . Mostly, you push commits (the word "mostly" is here because you also might normally push tags, including annotated tags).

This means the literal answer to the "how to push this directory" is that you can't. There are several alternatives though, depending on what sort of result you want, and most likely what you want is:

  1. clone the other repository and check out its master branch:

     cd $HOME/dir-where-you-work git clone git://host/other-repo 
  2. copy the directory and all its files from this repository to the other clone:

     cp -r project/MyWorkingDir/Dir1 other-repo 
  3. commit the result in the other clone:

     cd other-repo git add Dir1 git commit [write up a good commit message] 
  4. push the result

There are other, more complicated things you can do if you want some sort of different result, but I'll leave it at this here.

First I created one test project as app/ :-

[arup@~]$ mkdir app/
[arup@~]$ ls | grep app
app
[arup@~]$ cd app
[arup@app]$ touch a.txt
[arup@app]$ cat > a.txt
This is a test file.
^C
[arup@app]$ cat a.txt
This is a test file.
[arup@app]$ git init
Initialized empty Git repository in /home/arup/app/.git/
[arup@app]$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a.txt
nothing added to commit but untracked files present (use "git add" to track)
[arup@app]$ git commit -m "first commit"
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a.txt
nothing added to commit but untracked files present (use "git add" to track)
[arup@app]$ git add -A
[arup@app]$ git commit -m "first commit"
[master (root-commit) 5392f72] first commit
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt
[arup@app]$ git remote add origin git@github.com:aruprakshit/test-app_1.git
[arup@app]$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 231 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:aruprakshit/test-app_1.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

Now I have created another app /app2 :-

[arup@~]$ mkdir app2
[arup@~]$ cd app2
[arup@app2]$ touch README.md
[arup@app2]$ git init
Initialized empty Git repository in /home/arup/app2/.git/
[arup@app2]$ git add README.md
[arup@app2]$ git commit -m "first commit"
[master (root-commit) d044fe9] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
[arup@app2]$ git remote add origin git@github.com:aruprakshit/test-app_2.git
[arup@app2]$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:aruprakshit/test-app_2.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
[arup@app2]$ ls
README.md

Now, you can see under app2/ I have only README.md file. Now I will push from first project the file a.txt to this repository. So I did below :

[arup@app]$ git push -f git@github.com:aruprakshit/test-app_2.git
Counting objects: 3, done.
Writing objects: 100% (3/3), 231 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:aruprakshit/test-app_2.git
 + d044fe9...5392f72 master -> master (forced update)
[arup@app]$

Now checking if the file came to the second project :-

[arup@app2]$ git pull origin master
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:aruprakshit/test-app_2
 * branch            master     -> FETCH_HEAD
 + d044fe9...5392f72 master     -> origin/master  (forced update)
Merge made by the 'recursive' strategy.
 a.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt
[arup@app2]$ ls
a.txt  README.md
[arup@app2]$ cat a.txt
This is a test file.
[arup@app2]$

You can read the git-push(1) Manual Page documentation for the same.

Read GIT URLS

In general, URLs contain information about the transport protocol, the address of the remote server, and the path to the repository. Depending on the transport protocol, some of this information may be absent.

Git supports ssh, git, http, and https protocols (in addition, ftp, and ftps can be used for fetching and rsync can be used for fetching and pushing, but these are inefficient and deprecated; do not use them).

The following syntaxes may be used with them:

  • ssh://[user@]host.xz[:port]/path/to/repo.git/

  • git://host.xz[:port]/path/to/repo.git/

  • http[s]://host.xz[:port]/path/to/repo.git/

  • ftp[s]://host.xz[:port]/path/to/repo.git/

etc...

I did as git push -f git@github.com:aruprakshit/test-app_2.git , where I am sending from one repo's master to another's master branch. But you could create a separate branch , and then push the changes to that specific branch to the second repo's master branch too.

There are several ways to pull this off. It depends on the situation and the result you want.

  • Do the two repositories have any shared history?
  • Do you expect file3 and file4 to be merged or overwritten?
  • Do you want to retain the history of changes to file3 and file4 in the source repository?
  • Are the two repositories related, or is it just those two files?

First, clone the remote. We'll call this the destination repository.

If you don't want to retain the history, just copy file3 and file4 into the destination repository and commit it like normal. You're done!

From here on I'm going to assume they have no shared history, you expect a merge, and you want to retain history.

Then make the source repository a remote of the destination. Go into the destination repository and git remote add source <source url> . Git remotes will take all sorts of URLs and they will also take file paths. You can do git remote add source /path/to/My_Working_Dir .

Then fetch the other repository with git fetch source . Now your destination repository has a copy of the source to work with. Any shared history will be shared.

The next problem is to make git understand that Dir1/file3 in the source is file3 in the destination. As usual, there's several ways to accomplish this. I'm going with this technique because it's simplest.

This next step creates a connected point in history of the two repositories. This will retain the file history of the files. Without that connection, git can't do its job. git merge -s ours --no-commit source/master . -s is the strategy used to make the merge. ours means to ignore everything but "our" changes (ie. the destination). This prevents all the other files in the source from being merged, so the merge will contain no changes. --no-commit means to do the merge but not commit it (a merge is just a special commit with multiple parents). The merge should contain no changes, but it will provide a point of common history for the repositories.

We actually want Dir1/file3 and Dir1/file4 from the source. git read-tree -m -u source/master:Dir1 will copy them over and add them to the staging area. You will wind up with file3 and file4 changed to the source versions. Git won't have done a great job with the merge since they lack a common history. If you don't like how git merged them, you can make any modifications you like and git add them.

Commit the merge like any other commit. You should note in the commit log that you moved Dir1/* and what other actions you took during the merge and why.

Push as normal. You're pushing the entire history of the source repository, so it could be large.

You can remove the remote with git remote rm source . Because of the merge, the history will be retained.

If the source repository is large and its other contents mostly irrelevant, there are other techniques using git filter-branch to cut down the source repository to just the history of file3 and file4. Fortunately, you can use this technique and do that more complex trimming later. I'll let someone else cover that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM