43

I developed a project that was been developed by another developers. I sent my code to the previous developers to make changes in their code but they said that they have never worked with git, so they added changes to the project and it is now the actual version but not under version control.

So, I already have commits in github and I need to push this new version.

What I did:

  1. git init
  2. git remote add origin
  3. git add .
  4. git push origin master

But there is an problem: I can't push new changes before updating the local repo. If I update my repo it will return all the files that the previous developers have deleted.

How do I push the current version without pulling data from git?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Matrosov Oleksandr
  • 25,505
  • 44
  • 151
  • 277
  • Updating from the remote won't cause you to lose files, so long as you have them in your local commits. – alex Oct 10 '13 at 18:57

3 Answers3

78

You can do a forced push.

git push -f origin branch_name

The forced push will erase all commit history of the remote repository's branch, and replace it to your branch.

Check the answers for doing forced pushes in "How do I properly force a Git push?". Forced push can have unintended consequences as mentioned in "Git: How to ignore fast forward and revert origin [branch] to earlier commit?", so check for the same.

The forced push will be an incorrect way to push stuff in your case, since you already have previous commits on GitHub, and this will erase the commit history for previous commits.

Hence, to preserve your commit history, you can do the following things:

Remove all the files from the git repository, and then add the new files here, and then commit the updated files:

git rm -rf .
cp -r path/to/updated/code/* .
git add .

Doing a git status now will tell you which files the other developers modified, and a git diff will show what modifications are there.

If a file has remain unchanged, then git rm and git add will nullify the effect of each other.

The files which those developers deleted remain deleted since you ran the git rm for them but no git add.

Once you are satisfied that these indeed are the changes, you can commit using

git commit -m "Merged new code"

Potential gotchas:

  1. Only the file mode has changed (755 <=> 644) - depending on what code the other developers sent you.
  2. You will lose your .gitignore file with git rm -rf . (and similarly .gitattributes and other such files). Reset HEAD for each such files using git reset HEAD .gitignore before the commit.
  3. Different line terminating characters (in case different development environments are being used), So check for them appropriately.
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • I am one of the downvoters. I voted down because OP has an existing version controlled source which needs to be updated to include changes not currently in version control which were made by other people. Taking the current source sans VC, creating a single commit, and overwriting the existing history is the worst possible solution to the current edits not being tracked. There are times when forced pushes are useful or necessary, but this is by no means one of those cases. As my prior comment states, the proper way to handle this situation is to create new commits, not erase old ones. – cjc343 Oct 11 '13 at 17:15
  • @cjc343 I initially assumed OP wanted a new repo (got confused by the steps he was doing for `git init`). Thanks! I have updated my answer now. – Anshul Goyal Oct 11 '13 at 19:48
9

It seems like the other people worked on your project outside version control i.e upon bare files and folder.

I would suggest that you clone the repo, copy (and hence replace) the cloned content with the new content, commit and push these changes.

The current commands of git init etc you are using create completely new repos, which is not what you want.

Community
  • 1
  • 1
manojlds
  • 290,304
  • 63
  • 469
  • 417
  • 2
    Creating a new commit with the differences between the current repo state and current source state sounds like the best possible solution for this situation. It's dead simple, and keeps the history while recording the changes made by others properly. – cjc343 Oct 10 '13 at 19:47
  • 1
    I think the following link gives a better way http://stackoverflow.com/questions/10510462/force-git-push-to-overwrite-remote-files – Mani Oct 14 '15 at 13:56
5

Scenario:

In my case, the scenario was that I had a branch feature1 on which I made commits and after testing merged them to master.

But one day, I made a mistake and without much testing of changes in feature1, I merged the code to master. And then my teammate noticed that there's a bug. But there was no time to solve it for that day, but the master branch needs to have working code.

Making a Git Reset

I did a git log in my local, copied the commit id of the commit which I knew was working fine. And then did a reset by git reset --hard <commit id>.

This way we got back to the commit which was working. But when we tried to git push origin master this commit, git said to make a git pull first. But if we did that then we would again go to the latest commit which had the bug.

Solution - Force Push

Instead of simply git push origin master, we did

git push --force origin <commit id>:master

CAUTION: Forced Push deletes all the commit history which were above the forced pushed commit and will bring this commit to the top. Use Forced Push with caution.

To know more about solutions to some problems you might dive into:

  1. git push --force and how to deal with it
  2. Where do Commit Ids Come From
  3. Don't confuse between merge and rebase

TIP: While committing, commit with meaningful message of what you did in that commit. It does help.

Namaste

Deepam Gupta
  • 2,374
  • 1
  • 30
  • 33