Using git-tfs fetch to get latest causes a merge conflict - git-tfs

I have an issue attempting to pull my latest changes from TFS and adding them to a BitBucket repo. I have successfully pushed my branches into BitBucket, but when I attempt to get any new checkins from TFS I always get a merge conflict.
Steps:
git tfs clone http://TFS-ADDRESS/Collection $/Project/Name/Branch
git tfs init-branch $/Project/Name/NewBranch NewBranchName
git push -u origin --all
At this point my BitBukcet repo has all my files and history from TFS.
I then did a checking into me $/Project/Name/NewBranch on TFS.
Now I want to get the latest changesets from TFS and add/commit them into the BitBucket repository Note: At this point, no other branch in TFS or BitBucket has changed. The only change is my single check-in into TFS
When I do the following on my NewBranch, I get a merge conflict:
git tfs pull
Auto-merging Source/build.version
CONFLICT (content): Merge conflict in Source/build.version
As far as I can tell, it is trying to merge changes from my "master" to my "NewBranch", even though NewBranch is the latest code.
The ptfs pull command is pulling the last checgeset down, but then tries to do the merge. If I use
git tfs fetch --all
I see the changeset listed, but I cannot commit/push it to the BitBucket repository. I cannot find a reference online to say what I am doing wrong, or what steps I need to take (I am new to Git). Can anyone help?
I eventually want to automate this so any check-ins in TFS can be fetched and added to the BitBucket repository (until we eventually move all developers to BitBucket)
Thanks
EDIT
I am trying to take changes from TFS to BitBucket. Nothing is getting added to TFS from BitBucket.
All work is done on a branch (see below). Users are working in TFS. Users commit their changes there. NOTE: No-one is making edits to the BitBucket repo. It is a replica of TFS.
Once a day, I want to pull the latest changesets for each TFS branch down to my local git folder and them push them into BitBucket. The "git tfs fetch" retrieves the changesets:
D:\development\workspaces\git\anothertry>git tfs fetch --all
C83419 = 3abdaedf571369dce15f74a52697d86069f87d6d
but "git status" tells me there is nothing to commit
D:\development\workspaces\git\anothertry>git status
# On branch Feature
nothing to commit, working directory clean
And when I try to push this changeset into BitBucket, git tells me there is nothing to commit.
Branches
Master---o---------------o----o--o-o--o-------
\ / / / / /
Feature-----o----o--o-o--o

I seem to have found the answer after using Git Extensions.
It seems I need to do a fetch
git tfs fetch --all
This will get me all changesets from TFS for my trunk and any branches I have mapped (init-branch)
D:\development\workspaces\git\anothertry>git tfs fetch --all
C83454 = f65ba8d0cc7b40f42148ba2c06d0da8b7e968c4d
C83455 = 6c25feb6e74a09d0d3d84344002e7546044900ab
C83459 = 91c4450d702d5a97e862aedd7ad1b5af3ff2c375
C83460 = 5cacaba5bfe4197c1bf9fab498f51c1ba435e6ea
Next I need to perform a merge
git merge <guid>
NOTE: The is for the latest changeset (in this case 5cacaba...)
Updating 6c25feb..5cacaba
Fast-forward
Source/Common/w32threads.h | 1238 ++---
Source/xxxxxxx_Service/ServerAgent.cpp | 3638 ++++++-------
Source/xxxxxxx_Service/ServerAgent.h | 449 +-
Source/xxxxxxx_Service/User.cpp | 9073 ++++++++++++++++----------------
Source/xxxxxxx_Service/User.h | 647 +--
Source/build.version | 2 +-
6 files changed, 7562 insertions(+), 7485 deletions(-)
And, finally, push my changes to BitBucket
git push --all
So, it seems I was missing the git merge call and the parameters to pass to it.
Cheers

I don't exactly understand what you do bad but there is somethings that you should now in using git-tfs...
Working with a TFS branch
I see that you created a branch (step 2) and commit in that branch.
When you have checkouted your branch 'NewBranchName', you should checkin with the command :
git tfs rcheckin -i NewBranchName
and pull modifications with :
git tfs pull -i NewBranchName
or (with rebase)
git tfs pull -r -i NewBranchName
If you don't specify the -i option with the name of the TFS remote, you will check in your commit in the main branch (here, $/Project/Name/Branch ) :(
Checkin your commits on TFS
I give you above the command to check in your commits. But you should know that, for some reasons, when you check in a git commit in TFS, a new changeset in TFS is created (that's what we want ;) ) and after a new git commit is created. It's nearly the same that the original but with some informations (that you can see in the git comment).
Due to this fact, depending on what you do (and I don't exactly understand what), you could have problems because git try to merge commit with exactly the same modifications at the same place, so fail to merge automaticaly.
In fact, I think there is something wrong in your workflow because you shouldn't encounter this problem. Try to find the problem in your workflow.
I hope it will help.
Feel free to see the git-tfs wiki : https://github.com/git-tfs/git-tfs/wiki
I hope there is quite useful informations (partly did it, with love ;) )
PS : To help you better, can you tell me which command you use to checkin your commits?
checkin, checkintoo, rcheckin? rcheckin is heavily advised!
What I do to automate your workflow :
(here 'bitbucket' is the supposed name of your remote bitbucket repository)
=> in your master branch :
//Do your job & commit with git & ...
//rebase your work on TFS work
git tfs pull -r
//rcheckin with git-tfs
git tfs rcheckin
//commit in bitbucket repo
git push bitbucket master
=> in your 'NewBranchName' branch :
//Do your job & commit with git & ...
//rebase your work on TFS work
git tfs pull -r -i NewBranchName
//rcheckin with git-tfs
git tfs rcheckin -i NewBranchName
//commit in bitbucket repo
git push bitbucket NewBranchName
PS2 : Perhaps, you should have to stash your modifications if you have uncommited changes in your working directory before doing pull -r and rcheckin...
EDIT : You edit, I edit ;)
Before, I suppose that you have defined a remote for your bitbucket repository :
git remote add bitbucket https://bitbucket.org/yout_login/your_project.git
You have just to :
//checkout your branch
git checkout NewBranchName
//fetch the TFS changesets and merge your branch into
git tfs pull -r -i NewBranchName
//push your commit on bitbucket
git push bitbucket NewBranchName
And to explain a little what you are doing (and not understand totally :( )...
With "git tfs fetch --all", you are fetching the TFS changeset of all the branches but not merging (or rebasing) with your local branch. So they doesn't appear in your local branch.
You could see the DAG with the command to better understand :
git log --oneline --graph --decorate
The 'git tfs pull' given above merge the fetched commit with your branch so that will be good!
"git status" tells me there is nothing to commit
This command show you the files that are modified in the working directory. So, that's normal that you see no changes. That does say that your commit was not pulled!
And when I try to push this changeset into BitBucket, git tells me there is nothing to commit.
You should have! Are you sure to have define your remote toward your bitbucket repository? (see above)
Which command you use? What git tell you?

The git tfs fetch command doesn't update your local git repository, that's why you should do git merge after that.
To do the same in one command simply do pull from TFS remotes
git tfs pull -r
This should update local git repository with all new updates from TFS server
At this point you just need to push updates to git server:
git push -u origin --all

Related

Sync Git Branch to a specific folder

Suppose I have a git repo named waterkingdom It has lot of branches. We will be working with a specific branch called wave-pool.
wave-pool branch has files & folders such as
cost.txt
ride.txt
rules.txt
code/
code/ride.py
code/boom/crash.py
We have another folder which is not a part of the repo named wave-pool-boom
How can I only sync the branch wave-pool from waterkingdom repo to the folder called wave-pool-boom after the commit without knowing the latest commit hash?
Everything is locally on Linux.
How can I only sync the branch wave-pool from waterkingdom repo to the folder called wave-pool-boom after the commit without knowing the latest commit hash??
Everything is locally on LINUX.
Pushing branches from one repo to another is easily done in git, and makes a lot of sense the more you work with git.
Clone waterkingdom into a new directory
git clone --single-branch -b wave-pool /path/to/waterkingdom ~/projects/waterkingdom
cd ~/projects/waterkingdom
Setup a new remote
git remote add r-wave-pool-boom /path/to/wave-pool-boom
Push the branch to the remote (but do not change its tracked remote branch)
git push r-wave-pool-boom wave-pool
Remove the remote (optional)
git remote remove r-wave-pool-boom
Tools to help you further your Git knowledge
git branch -avv
Gives a listing of all branches and what remote branch (if any) they track, what the latest commit hash/message is, and the state (behind, ahead) of each branch.
git remote -v
Give a listing of all the remotes (if any) and their URL's configured for your local repo.
Further comments
Why "without knowing the latest commit hash"? The latest commit hash is always HEAD or <branch-name> or refs/remotes/origin/<branch-name>.

What is the best way to mirror a repo and fetch updates on a daily basis?

I don't know if this is the right way to accomplish what I need and maybe has also been asked a lot, although I couldn't find a solution.
I have mirrored a repository into my Gitlab account via
git clone --mirror https://github.com/some/repo
git remote rename origin upstream
git remote add origin git#gitlab.com:user/my-repo.git
git push origin --all
Now I want to frequently get the changes from the upstream repository without using git pull or git merge, because I want the commits to be identical to the upstream branch and not "Merging upstream into origin..." commits. From what I understand, you need to
cd my-repo
git remote add https://github.com/some/repo
git checkout branch_name
git pull --rebase upstream branch_name <-- pulls the changes without merging them
git rebase <-- rebases to the fetched changes so my own changes will stay on top
This works if I do it manually for the branch, but if I want to iterate through all branches with. Please correct me if I am approaching this the wrong way!
for branch in $(git for-each-ref --format='%(refname)' refs/remotes/origin); do branch=${branch##*/}; echo "\nUpdating $branch..."; git checkout $branch; git pull --rebase upstream $branch; git rebase; done
it doesn't work and the local branches stay untouched.
I know that Gitlab provides its own mirroring tool, but it is not activated in our company.
This seems to me to be a misunderstanding of what a branch is and what it's for. You should not have any local branches corresponding to the upstream. Just git fetch and stop; you are now mirrored and up to date.

Push current code to existing GitHub repository

I have several Visual Studio solutions that have both a local repository and one on GitHub. I've already made many changes and successfully pushed those changes to GitHub.
But now Visual Studio has forgotten that one of my local repositories is associated with a GitHub repository and I can't seem to figure out how to reconnect it. In fact, it no longer lists that repository in my list of GitHub repositories.
In the image below, you can see I have a local repository called Toxic, but that repository does not appear in the list of GitHub repositories. If I try publishing the Toxic project to GitHub, it just tells me the repository already exists.
How the heck can I get all of my existing Github repositories to show up in the top section shown above so I can push my latest changes?
it appears the only option is to clone the GitHub repository locally, copy my modified files over the newly created repository, and then check in my changes.
Try fist:
installing Git for Windows (command-line)
cloning your remote repo in a new folder
adding your existing repository as a remote
fetching and see if you can cherry-pick your commits
That is:
git clone https://github.com/<user>/<repo> newFolder
cd newFolder
git remote add old ../path/to/old/local/repo
git fetch old
git log old/master
git cherry-pick old-sha1..old/master
(with old-sha1 being the first commit you want back)
Then add the newFolder in your Visual Studio workspace, and see if everything works (do a modification, add, commit and push)
Unless I'm missing something, it appears the only option is to clone the GitHub repository locally, copy my modified files over the newly created repository, and then check in my changes.
Of course, I lose all my comments and iterations since the last check in to GitHub. And care had to be taken not to delete the .git folder, and to copy over all changed file and delete any that had been removed. Seems like there should be an easier way but this certainly did the trick.
I'm no git expert, but I think I might be able to help, if I'm not too late.
Run:
git remote -v
This should print something in the form of:
origin <remote_repo_url> (fetch)
origin <remote_repo_url> (push)
If you only see:
origin (fetch)
origin (push)
try running:
git remote set-url origin <remote_repo_url>
If you get no output then run:
git remote add origin <remote_repo_url>
And then try
git push -u origin
The -u or --set-upstream flag will set origin as the default repo for your branches.

Reinitializing a git repository

I have an xcode project on my desktop in a directory that originally had a git repository with a tracking branch that tracked a remote branch on github. The remote branch has some 84 commits and is 2 commits ahead of the master branch of the project I'm adding features to. I changed the name of the folder/directory on my desktop. I'm not 100% sure if this is the reason why but when I go to git status I get: fatal: Not a git repository (or any of the parent directories): .git. My plan is to simply git Init, add the remote branch and create a new tracking branch and than commit locally to that branch and than push to the remote branch. However, I'm a git beginner and I'm not sure if this is the proper way to go about it. I'm very weary of losing any commit history or accidentally breaking something. Is the method I outlined a good way of rectifying this loss of the git repo?
If you have all your code updated in remote repo then your local .git is deleted. You don't need to re-init your local repo. Rather just clone it.
git clone remote_repo
If you don't have any commit in remote repo, Simply follow
git init
git add all_local_files
If you have updated remote repo than some commits made in local but not pushed and you lost .git. Simply clone remote. Add all files in a single commit
git clone
git add all_local_files
Looks like you messed up your git repository, but not the code / contents.
One way to restore and keep local changes ( if any ) would be:
Clone another copy of your repo from github.
Copy all modified files to the new repo, omitting removed ones: rsync -duztv /old/local/repo/ /new/local/repo
git status to see what the situation is.

When git tfs could not create a merge commit, how to correct it

When git tfs could not create a merge commit, it says
warning: this changeset 7504 is a merge changeset. But it can't have been managed accordingly because one of the parent changeset 7494 is not present in the repository! If you want to do it, fetch the branch containing this changeset before retrying...
As per the documentation, Note: if you see a warning, you could correct that by reseting the tfs remote to a previous commit. Then fetch the merged branch and retry to fetch the branch.
Can anyone please elaborate on reseting the tfs remote to a previous commit. Though, I've now fetched the merged branch, I don't understand how do I reset it to previous commit to the failed one. I'm not sure but do I have to git checkout <hash of the previous commit>?
Yes, now git-tfs try to create merge commit when it encounter merge changesets (now that it has a satisfying branch support).
This message is just a warning message and when you see it, you have 2 options...
The first one is to do nothing because you know that it was, for exemple, an old feature branch that you will never work on that and MORE IMPORTANT that in the future you will never merge again in your parent branch.
The second one is if you really want to have this merge commit. Because you want a good history or MORE IMPORTANT because you still work on this branch and will have to merge it in the parent branch.
To do that, you will have to reset your tfs remote (because in fact the commit has already been created --to keep compatibility with how git-tfs works in previous version and for those that can't work with branches--).
To reset your remote, you must use reset-remote command.
Then intitialized the branch that is merged in the parent branch with branch --init.
Reset also the local branch to the tfs remote (due to an internal git-tfs optimization).
And fetch again the parent branch. Now that the merged branch exist and is fetch, git-tfs will find the parent changeset from the merged branch and you will have a beautiful merge commit in your git repository ;)
So, If you did this earlier
git tfs clone https://CompanyName.visualstudio.com/DefaultCollection "$/CompanyName/Main" KfGitMain --workspace="C:\TFS\Main"
cd GitMain
git tfs branch --init "$/CompanyName/Release/20140121.1" live20140121.1
git tfs branch --init "$/CompanyName/Release/20140121.1-hotfix" hotfix20140121.1
and if you received the warning for all the three due to code merges to and from each other, so you will have to
git checkout hotfix
git tfs reset-remote 5fb83335b8dfc6fbb96e0a54a48dc06c506e3277 ## previous commit of the first failed commit
git reset --hard tfs/hotfix
git tfs pull -i hotfix
git checkout live
git tfs reset-remote eba62a1446f3f81676d051336ca254fe54c37d74
git reset --hard tfs/live
git tfs pull -i live
git checkout master
git tfs reset-remote 72727737ec52f9b96d22d343770186a342c8b166
git reset --hard tfs/default
git tfs pull -i default
Note: if you don't have too many branches and/or strange tfs history, all that could be avoided using git clone with the option --with-branches that will init and fetch all the branches taking care of the merge changesets

Resources