Clone a git-svn repo by getting all of the svn part from the original svn repo - linux

How can I clone a git repo from my laptop (at home) to a server (at university) while getting most of the repo from a third (svn) repo at another uni that is the main codebase. I'd like to minimise the amount of home<->uni traffic by maximising uniOne<->uniTwo traffic.
this is what I have now on Laptop:
--o--o--o---o---o---o git-svn trunk
`--o--o-o--o git mybranch
this is what I would like to get on uniOne:
--o--o--o---o---o---o git-svn trunk <-- from uniTwo
`--o--o-o--o git mybranch <-- from Laptop
After cloning the repo should be able to pull branches from Laptop.
I have tried: on uniOne: git-svn clone uniTwo, git remote add Laptop, but then git fetch wants to get the whole thing from Laptop. I thought maybe using git clone --depth x Laptop and then graft them together might work but it still requires all of the source files to be transfered Laptop->uniOne, not just the changes. I could try to export all patches from Laptop and apply them on top of a fresh svn checkout then get it to track the branch on my Laptop (if that is possible) but it would be easier to wait until I am next at uni and then just clone normally.

Let's define your repositories:
git-svn <-- this is the Subversion repository at University
uni/master <-- this is a Git repository at your University. This is jus a "fetching repository" that gets the latest history from the Subversion repo.
laptop/master <-- This is the Git repository on your laptop. This is where you work.
I would suggest the following setup:
Create uni/master by doing git svn clone of git-svn.
Automatically or regularly update uni/master with the latest changes from git-svn by running git svn rebase (trigger with a commit hook, cron-job, or manually every time you're at Uni).
Create laptop/master by cloning uni/master. Here you can commit locally as often as you want. When you are at University, get the latest changes from uni/master by running git pull --rebase (you always have to do --rebase to keep history linear, because SVN won't understand git-branches).
When you want to push changes from your laptop back to git-svn, you have to configure the git-svn remote on your laptop/master first:
git svn init https://url.to.uni-svn-repo
Now you can push your latest changes back to uni-svn with git svn dcommit. Note that you might have to update the reference to the latest commit in uni/master first. first:
git update-ref refs/remotes/git-svn refs/remotes/uni/master
DO NOT attempt to push from your laptop/master to uni/master. This will only bring chaos as the rebasing/rewriting history will just confuse Git when it tries to sync with git-svn again.
See also http://www.tfnico.com/presentations/git-and-subversion where I've started collecting up a bunch of tips for working with Git and SVN together.

Related

How do I keep a git clone updated?

I am developing a project on my laptop that is to be implemented on my VPS. I am continually making updates on my laptop and pushing them to my git repo, but I am in the dark on how I should keep the clone I made on my server, updated.
When I try to run git clone <url> in my directory, it tells me 'file already exists!' or something along those lines. Do I just delete the entire folder and reclone the repo like that? Or is there a way, other than initiating the directory as git, and creating an upstream, that I can reclone without having to delete everything first?
How do I keep a git clone updated?
I generally clone git project.
git clone git#source.golabs.io:mobile/project-name.git
and after that I start developing my feature by creating new branch branch.
so for up to date with remote project you need to checkout to master branch. and just do
git pull and sync your project using ./gradlew clean build
If your project have submodules- you need to do
git submodule update --init --remote --recursive
try to use git pull. it will automaticly analyze the difference .And try to fix it
Instead of having to go to your server and pulling, you could setup a listener in order to do the pull for you.
For instance, if you are ushing to GitHub or BitBucket or GitLab, you can setup a webhook (GitHub webhook, BitBucket webhook, GitLab webhook), and a local listener in order detect the push, and triggger a git -C /path/to/your/repo pull.

move local repo to remote single file [duplicate]

This question already has answers here:
How do I move my local Git repository to a remote Git repository
(9 answers)
Closed 6 years ago.
I apologize if this has been asked somewhere else and I missed it. I've found many questions and answers that are close to what I'm trying to do, but none that fit exactly.
I have local files and projects in a local git repository. I created the repository a few months back as a way to safeguard and track my own work. The rest of our company uses SVN so I am the first to use git here. I set it up in my home directory on a Linux server. This repo contains many commits, branches, and tags that span my work over the past few months.
I want to move that repo to a more accessible location within our company's Linux server (not in my home directory) so others can clone and work with the entire repo (including all the tags, branches, history, etc.) as they see fit.
I've thought about copying or moving the entire file structure, but I want it to be a single file - i.e. myRepo.git.
How do I do this so that myRepo.git contains all the information I've committed such that when someone clones this repo and runs 'gitk --all', they will see all the branches, tags, etc.?
Thanks for your help.
You can git clone --bare your repo from somewhere other people can access it.
The most basic remote Git repo is nothing but a bare clone. A bare clone means it doesn't have a checkout, it's just the contents of the .git directory. Having a checkout would mean people might try to use that checkout as their own git working directory and make changes and that would get confusing with other people pushing changes to the repository.
For example, I'll make a new repository in foo/ and commit a file.
$ git init foo
Reinitialized existing Git repository in /Users/schwern/tmp/foo/.git/
$ rm -rf foo
$ git init foo
Initialized empty Git repository in /Users/schwern/tmp/foo/.git/
$ cd foo
$ touch this
$ git add this
$ git ci -m 'First commit'
[master (root-commit) 1a0bddf] First commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 this
Then I'll make a bare clone of it into bar/ (cloning doesn't have to happen over a network).
$ git clone --bare foo bar
$ ls
HEAD config description hooks info objects packed-refs refs
Instead of the checkout, it has the contents of the .git directory.
Now I can clone from that.
$ git clone bar baz
Cloning into 'baz'...
done.
$ cd baz/
$ git log
commit 1a0bddf415f48d71fa3aacc79c07c233d91ed4a9 (HEAD -> master, origin/master, origin/HEAD)
Author: Michael G. Schwern <schwern#pobox.com>
Date: Tue Feb 14 12:01:13 2017 -0800
First commit
That's cloning on a local filesystem. Git will, of course, clone over a network. Typically it uses ssh or https. git clone user#host/path is really sshing into host as user and copying what's in path.
So you can put your repo anywhere the other folks have ssh access, like a dev server, or the same host that has the SVN server.
That's the most bare bones way to share your Git repository. There are plenty of more sophisticated Git servers out there that provide web access and more protocols. Everything from the very sparse GitWeb to Gitlab, a Github clone you can host locally for free.
You can read more about this in Pro Git's chapter on Git Servers.
A fully functional git repo is not a single file, and there is no way to make it so. That said, copying your working repo isn't the best thing to do either.
If having a single file is more important that having the repo be fully functional - i.e. you don't care if your coworkers can push to it - then you can create a bundle file.
git bundle create /path/to/my/repo.bundle --all
Your coworkers can clone from this, add it as a remote, pull or fetch from it... but they can't push to it (and neither can you; to add to it you'd have to recreate it).
A shared repo to be cloned from should normally be a bare repo. This is roughly equivalent to a copy of the .git directory from your working repo. If your existing repo is at /path/to/my/repo, you can create a suitable bare repo at /path/to/shared/repo by saying
cd /path/to/shared
git clone --mirror /path/to/my/repo
Note that I used --mirror instead of --bare; this has to do with how refs are copied and will work better if you intend this to be treated as the origin henceforth.
And yet at this point /path/to/my/repo is still considered the upstream. To fix that
cd /path/to/shared/repo
git remote remove origin
cd /path/to/my/repo
git remote add origin /path/to/shared/repo

How to copy commits from one Git repo to another?

Last week I created a Github repo and forgot to select a license for the repo. Now there are already 3 large commits.
I have asked the 3 contributors if it is ok if I delete the repo and then create it again with the same name and this time selecting the license when creating the repo, and they were fine with that.
Question
Is there a way I can get the commits into the new repo (this time the first commit is the LICENSE file) and still keep the commit meta info?
Is there a way I have get the commits into new repo (this time the first commit is the LICENSE file) and still keep the commit meta info?
Yes, by adding a remote and cherry-picking the commits on top of your first commit.
# add the old repo as a remote repository
git remote add oldrepo https://github.com/path/to/oldrepo
# get the old repo commits
git remote update
# examine the whole tree
git log --all --oneline --graph --decorate
# copy (cherry-pick) the commits from the old repo into your new local one
git cherry-pick sha-of-commit-one
git cherry-pick sha-of-commit-two
git cherry-pick sha-of-commit-three
# check your local repo is correct
git log
# send your new tree (repo state) to github
git push origin master
# remove the now-unneeded reference to oldrepo
git remote remove oldrepo
The rest of this answer is if you still want to add the LICENSE to your previous repo.
Yes. You can place your LICENSE commit as the first commit by rebasing.
Rebasing is gits way of rearranging commit order while keeping all the commit authors and commit dates intact.
When working on a shared repo, it's generally discouraged unless your entire team is git-fluent. For those that aren't, they can just clone a fresh copy of the repository.
Here's how you get your LICENSE commit as the first commit.
1. Update and rebase your local copy
Check out your project and place the LICENSE file in a commit ON TOP of your current 3 commit stack.
#create LICENSE file, edit, add content, save
git add LICENSE
git commit -m 'Initial commit'
Then do an interactive rebase on the master branch to REARRANGE the commits.
git rebase -i --root
It will open an editor. Move the bottom line (your "Initial commit" commit, the most recent commit) to the top of the file. Then save and quit the editor.
As soon as you exit the editor, git will write the commits in the order you just specified.
You now have your local copy of the repository updated. do:
git log
to verify.
2. Force push your new repo state to github
Now that your copy is updated, you have to force push it to github.
git push -f origin master
This will tell github to move the master branch to its new location.
You should only force push in rare occasions like this where everybody working with it is aware of the pending change, else it will confuse your collaborators.
3. Synchronize collaborators to github
Lastly, all the collaborators will have to synchronize to this repository.
First they must have clean repositories as the following command can be destructive if there are unsaved changes.
# make sure there are no unsaved changes
git status
# pull the latest version from github
git fetch
# move their master branch pointer to the one you published to github.
git reset --hard origin/master
That's it. Everybody should be in sync now.
I had a similar problem where I forgot to fork a repo to my github and added several commits before I realized my mistake.
I found a pretty simple solution.
First remove the remote to the original repo
git remote remove origin
Second add a remote to the new fork on my github
git remote add origin <my repo URL>
Then I pushed to origin master and all of my commits showed up on my github.
I used the following approach:
Clone the source repo to a folder like /c/SrcRepo
Clone the destination repo to a folder like /c/DstRepo and switch to the destination branch
In the root folder of the destination repo run the command:
git pull /c/SrcRepo srcBranch --allow-unrelated-histories
No necessary to create an additional remote reference
Based on #Moocowmoo's answer but trying to streamline it bit more
What this does differently is tries to avoid conflicts as much as possible, just assuming that the remote is correct.
It doesn't however handle deleted files well, so there is still a manual element.
# assuming you are already on the branch you want to be
git remote add oldrepo https://github.com/path/to/oldrepo
git fetch oldrepo
# take all or subset of changes from a branch
git cherry-pick --strategy recursive --strategy-option theirs oldestCommitHash^..latestCommitHash
# or take all changes included in a specific merge commit (easiest)
git cherry-pick --strategy recursive --strategy-option theirs mergeCommitHash^..mergeCommitHash
# handling deleted files/unhandled conflicts
# just keep repeating this section
git mergetool
# either c/m or d based on if you want to keep or delete the files
git cherry-pick --continue
Destination Git = UrlD (existing content doesn't matter)
SourceGit = UrlS
git clone UrlS
git remote add origin2 UrlD
git push -f origin2 master
Now the Destination will have the same data as Source(You can also use origin instead of origin2)
you can try this, it's easy and straightforward. This will push all commits before (and including) the hash you use as <last-commit-hash-from-old-repo> to the other repo:
git clone https://github.com/path/to/new-repo.git new-repo
cd new-repo
git remote add old https://github.com/path/to/old-repo.git
git remote update
git merge --allow-unrelated-histories <last-commit-hash-from-old-repo>
git push origin main
if anyone needs to push all commits from a repo to another as a single commit (like I needed), you can simply add --squash to the merge command like this:
git clone https://github.com/path/to/new-repo.git new-repo
cd new-repo
git remote add old https://github.com/path/to/old-repo.git
git remote update
git merge --squash --allow-unrelated-histories <last-commit-hash-from-old-repo>
git push origin main
In my case I needed to find out differences between the old and new repos. So in the new repo added the old one.
git remote add old https://gitlab.site.az/old-blog.git
Fetch all remotes
git fetch --all
Find different commits
git log --graph --oneline --pretty=format:"%h%x09%an%x09%ad%x09%s" --abbrev-commit --date=relative develop..old/develop
Get commits you selected
git cherry-pick SHA1 SHA2 SHA4

Added BitBucket repo as remote on GitHub

I've just installed git on Ubuntu, now I want to work on my repo in BitBucket. I'm a little confused on how to do so. I can't do the following:
git remote add BitBucketRepo git#bitbucket.org:dir/file.git
As it returns the following error:
fatal: Not a git repository (or any of the parent directories): .git
It clearly is pointing to a git repo, so why is it lying to me?
Also, it is worth noting I am using SSH and I have successfully paired my GitHub account to my computer.
You need to run this command from a local git repository (a directory in which you have run git init or git clone) - otherwise git remote doesn't know which local repo you want to add the remote for.
It should be as simple as cd my-local-dir, where my-local-dir is the directory containing your local (cloned) git repository.
If you don't yet have the repo available locally:
git clone git#github.com:...etc... my-local-dir
cd my-local-dir
git remote add ButbucketRepo git#bitbucket.org...
git push -u ButbucketRepo master
This will clone your code from Github into the my-local-dir directory, add your BitBucket repo as a remote repository, push your code up to Bitbucket and set the local master branch to track the BitBucket remote's master branch.
Tracking means that commands that involve a remote like git push will automatically use the BitBucket remote's master branch. If you don't want that behaviour, skip the -u option.

Git - Syncing a Github repo with a local one?

First off, forgive me if this is a duplicate question. I don't know anything but the basic terminology, and it's difficult to find an answer just using laymen's terms.
I made a project, and I made a repository on Github. I've been able to work with that and upload stuff to it for some time, on Windows. The Github Windows application is nice, but I wish there was a GUI for the Linux git.
I want to be able to download the source for this project, and be able to edit it on my Linux machine, and be able to do git commit -m 'durrhurr' and have it upload it to the master repository.
Forgive me if you've already done most of this:
The first step is to set up your ssh keys if you are trying to go through ssh, if you are going through https you can skip this step. Detailed instructions are provided at https://help.github.com/articles/generating-ssh-keys
The next step is to make a local clone of the repository. Using the command line it will be git clone <url> The url you should be able to find on your github page.
After that you should be able to commit and push over the command line using git commit -am "commit message" and git push
You can use SmartGit for a GUI for git on Linux: http://www.syntevo.com/smartgit/index.html
But learning git first on the command line is generally a good idea:
Below are some basic examples assuming you are only working from the master branch:
Example for starting a local repo based on what you have from github:
git clone https://github.com/sampson-chen/sack.git
To see the status of the repo, do:
git status
Example for syncing your local repo to more recent changes on github:
git pull
Example for adding new or modified files to a "stage" for commit
git add /path/file1 /path/file2
Think of the stage as the files that you explicitly tell git to keep track of for revision control. git will see the all the files in the repo (and changes to tracked files), but it will only do work on the files that you add to a stage to be committed.
Example for committing the files in your "stage"
git commit
Example for pushing your local repo (whatever you have committed to your local repo) to github
git push
What you need to do is clone your git repository. From terminal cd to the directory you want the project in and do
git clone https://github.com/[username]/[repository].git
Remember not to use sudo as you will mess up the remote permissions.
You then need to commit any changes locally, i.e your git commit -m and then you can do.
git push
This will update the remote repository.
Lastly if you need to update your local project cd to the required directory and then:
git pull
To start working on the project in linux, clone the repo to linux machine. Add the ssh public key to github. Add your username and email to git-config.
For GUI you can use gitg.
PS : Get used to git cli, It is worth to spend time on it.

Resources