问题
I produced a diff.txt file with the command (executed from ~):
diff -r /full/path/to/directory/A /full/path/to/directory/B > diff.txt
The generated diff file looks good.
Now I run (always from ~)
patch -p0 <diff.txt
or I also tried:
patch <diff.txt
I would expect it to apply the changes to the files in /full/path/to/directory/A so that after the operation they will be identical to those in /full/path/to/directory/B
But it only says: * Only garbage was found in the patch input.
What am I missing?
EDIT: Here is the whole diff file:
diff /media/DATA/lavoro/eclipse_workspace/ODK Collect/src/net/xxx/collect/android/activities/FormEntryActivity.java /media/DATA/lavoro/xxx/backups/odk src embedded maps/net/xxx/collect/android/activities/FormEntryActivity.java
21a22,27
>
> import com.google.android.maps.GeoPoint;
> import com.google.android.maps.MapActivity;
> import com.google.android.maps.MapView;
> import com.google.android.maps.MyLocationOverlay;
>
36a43
> import net.xxx.collect.android.widgets.GeoPointWidget;
50a58,60
> import android.location.Location;
> import android.location.LocationListener;
> import android.location.LocationManager;
86a97
> import java.util.List;
96,97c107,108
< public class FormEntryActivity extends Activity implements AnimationListener, FormLoaderListener,
< FormSavedListener, AdvanceToNextListener, OnGestureListener {
---
> public class FormEntryActivity extends MapActivity implements AnimationListener, FormLoaderListener,
> FormSavedListener, AdvanceToNextListener, OnGestureListener, LocationListener {
115a127,133
>
> // Release:
> private static final String GMAPS_API_KEY="0SH1_CwvF7Nn4_kT8NcGTc8vMCjrqIdpXOjSqcA";
>
> // Debug:
> //private static final String GMAPS_API_KEY="0SH1_CwvF7Nm8oPeWuNskdKCKKWZ1VlGx6mqTfg";
>
162a181,190
>
> private MapView mMapView;
> private boolean mGPSOn = false;
> private boolean mNetworkOn = false;
> private MyLocationOverlay mLocationOverlay;
> private LocationManager mLocationManager;
> private Location mLocation;
> private GeoPoint mGeoPoint;
>
> private boolean flingEnabled=true;
171a200
> Log.d(t, "onCreate "+(savedInstanceState==null?"":" with savedInstanceState"));
207a237,240
> Log.d(t, "savedInstanceState "+(newForm?"seems":"does not seem")+" to be a new form");
> }
> else {
> Log.d(t, "savedInstanceState does not have a newForm key");
223a257
> Log.d(t,"Last non configuration instance is a FormLoaderTask");
225a260
> Log.d(t,"Last non configuration instance is a SaveToDiskTask");
227a263
> Log.d(t,"Last non configuration instance is null");
228a265
> Log.d(t," and the form is not new");
298a336,360
>
>
> mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
> List<String> providers = mLocationManager.getProviders(true);
> for (String provider : providers) {
> if (provider.equalsIgnoreCase(LocationManager.GPS_PROVIDER)) {
> mGPSOn = true;
> }
> if (provider.equalsIgnoreCase(LocationManager.NETWORK_PROVIDER)) {
> mNetworkOn = true;
> }
> }
> if (!mGPSOn && !mNetworkOn) {
> Toast.makeText(getBaseContext(), getString(R.string.provider_disabled_error),
> Toast.LENGTH_SHORT).show();
> //finish();
> }
>
> }
>
> public void enableFling() {
> flingEnabled=true;
> }
> public void disableFling() {
> flingEnabled=false;
300d361
<
303a365
> Log.d(t,"onSavedInstanceState");
312a375
> Log.d(t,"onActivityResult "+requestCode+" "+resultCode+" "+intent.getAction());
457a521
> Log.d(t,"refreshCurrentView");
610a675
> Log.d(t,"onRetainNonConfigurationInstance");
612,613c677,680
< if (mFormLoaderTask != null && mFormLoaderTask.getStatus() != AsyncTask.Status.FINISHED)
< return mFormLoaderTask;
---
> if (mFormLoaderTask != null && mFormLoaderTask.getStatus() != AsyncTask.Status.FINISHED){
> Log.d(t," returning mFormLoaderTask");
>
> return mFormLoaderTask;
614a682,683
> }
>
616,618c685,689
< if (mSaveToDiskTask != null && mSaveToDiskTask.getStatus() != AsyncTask.Status.FINISHED)
< return mSaveToDiskTask;
<
---
> if (mSaveToDiskTask != null && mSaveToDiskTask.getStatus() != AsyncTask.Status.FINISHED) {
> Log.d(t," returning mSaveToDisk");
>
> return mSaveToDiskTask;
> }
620a692
> Log.d(t, " just saving answers. No need to pass mFormController");
622a695
> Log.d(t," returning null");
772c845
< private void showNextView() {
---
> public void showNextView() {
1316a1390,1391
> mLocationManager.removeUpdates(this);
> if (mLocationOverlay!=null) mLocationOverlay.disableMyLocation();
1322a1398
> Log.d(t,"nResume");
1323a1400,1407
> if (mLocationOverlay!=null) mLocationOverlay.enableMyLocation();
> if (mGPSOn) {
> mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
> }
> if (mNetworkOn) {
> mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
> }
>
1337a1422,1426
>
>
>
>
>
1367a1457,1477
> Log.d(t,"---- onDestroy ----");
> boolean problem=false;
> if (mFormLoaderTask != null && mFormLoaderTask.getStatus() != AsyncTask.Status.FINISHED){
> Log.d(t," I wish I could retain mFormLoaderTask");
> problem=true;
> }
> else if (mSaveToDiskTask != null && mSaveToDiskTask.getStatus() != AsyncTask.Status.FINISHED) {
> Log.d(t," I wish I could retain mSaveToDisk");
> problem=true;
> }
> else if (mFormController != null && currentPromptIsQuestion()) {
> Log.d(t, " I wish I had the opportunity to save answers");
> problem=true;
> }
>
> if (!problem) Log.d(t," everything seems ok");
>
>
>
>
>
1369c1479
< mFormLoaderTask.setFormLoaderListener(null);
---
> mFormLoaderTask.setFormLoaderListener(null);
1373a1484
> Log.d(t," Cancelling and destroying form loader task");
1376a1488,1489
> else Log.d(t," Not cancelling form loader task because it's not done");
>
1382a1496
> Log.d(t," Cancelling save to disk task");
1394a1509,1512
> if (mCurrentView!=null && mCurrentView instanceof ODKView)
> for (QuestionWidget qw : ((ODKView) mCurrentView).getWidgets()) {
> qw.onInAnimationDone();
> }
1607c1725,1726
< if (Math.abs(e1.getX() - e2.getX()) > 60 && Math.abs(e1.getY() - e2.getY()) < 60) {
---
> if (!flingEnabled) return false;
> if (Math.abs(e1.getX() - e2.getX()) > 60 && Math.abs(e1.getY() - e2.getY()) < 60) {
1631c1750
< // We don't wnat that, so cancel it.
---
> // We don't want that, so cancel it.
1645a1765,1842
>
>
> @Override
> protected boolean isRouteDisplayed() {
> // TODO Auto-generated method stub
> return false;
> }
>
> public MapView getMapView() {
> if (mMapView==null) {
> Log.d("FormEntryActivity", "Creating MapView");
> mMapView=new MapView(this, GMAPS_API_KEY);
> mMapView.setBuiltInZoomControls(true);
> mMapView.setSatellite(false);
> mMapView.getController().setZoom(16);
> createLocationOverlay();
> }
> return mMapView;
> }
> public MyLocationOverlay getLocationOverlay() {
> return mLocationOverlay;
> }
>
> public void createLocationOverlay() {
> Log.d("FormEntryActivity", "createLocationOverlay");
> mLocationOverlay=new MyLocationOverlay(this,mMapView);
> mMapView.getOverlays().add(mLocationOverlay);
> mLocationOverlay.enableMyLocation();
> }
>
>
> @Override
> public void onLocationChanged(Location location) {
> if (true) {
> Log.d("FormEntryActivity", "onLocationChanged");
> mLocation = location;
> if (mLocation != null) {
>
> mGeoPoint =
> new GeoPoint((int) (mLocation.getLatitude() * 1E6),
> (int) (mLocation.getLongitude() * 1E6));
> if (mCurrentView!=null && mCurrentView instanceof ODKView)
> for (QuestionWidget qw : ((ODKView) mCurrentView).getWidgets()) {
> if (qw instanceof GeoPointWidget) {
> ((GeoPointWidget)qw).onLocationChanged();
> }
> }
>
> }
> }
> }
> public GeoPoint getGeoPoint() {
> return mGeoPoint;
> }
> public Location getLocation() {
> return mLocation;
> }
>
>
> @Override
> public void onProviderDisabled(String provider) {
> // TODO Auto-generated method stub
>
> }
>
>
> @Override
> public void onProviderEnabled(String provider) {
> // TODO Auto-generated method stub
>
> }
>
>
> @Override
> public void onStatusChanged(String provider, int status, Bundle extras) {
> // TODO Auto-generated method stub
>
> }
diff -r /media/DATA/lavoro/eclipse_workspace/ODK Collect/src/net/xxx/collect/android/widgets/GeoPointWidget.java /media/DATA/lavoro/xxx/backups/odk src embedded maps/net/xxx/collect/android/widgets/GeoPointWidget.java
19a20,24
>
> import com.google.android.maps.GeoPoint;
> import com.google.android.maps.MapView;
> import com.google.android.maps.Overlay;
>
27a33
> import android.location.Location;
31a38
> import android.view.ViewGroup;
34a42
> import android.widget.RelativeLayout;
37a46
> import java.util.List;
47a57
> private Button mAcceptButton;
55c65,73
<
---
>
> private MapView mMapView;
> private FormEntryActivity mFEA;
> private TextView mLocationStatus;
>
> private RelativeLayout mMapContainerLayout;
>
> private LinearLayout.LayoutParams lp;
> RelativeLayout.LayoutParams rlp;
59c77,79
<
---
>
>
>
113c133
< if (mAppearance != null && mAppearance.equalsIgnoreCase("maps")) {
---
> if (mAppearance == null || mAppearance.equalsIgnoreCase("maps")) {
133,141c153
< Intent i = null;
< if (mUseMaps) {
< i = new Intent(getContext(), GeoPointMapActivity.class);
< } else {
< i = new Intent(getContext(), GeoPointActivity.class);
< }
< ((Activity) getContext()).startActivityForResult(i,
< FormEntryActivity.LOCATION_CAPTURE);
< mWaitingForData = true;
---
> launchMap();
148,149c160,186
<
< addView(mGetLocationButton);
---
> mFEA=(FormEntryActivity)context;
> //addView(mGetLocationButton);
> Log.d("GeoPointWidget","Adding ViewMap in constructor");
>
> setUpMapContainer();
> }
>
> protected void setUpMapContainer() {
> lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
> lp.setMargins(0, 0, 0, 0);
>
> rlp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
> rlp.setMargins(0, 0, 0, 0);
>
> mMapContainerLayout=new RelativeLayout(mFEA);
> mMapContainerLayout.setLayoutParams(lp);
>
> this.addView(mMapContainerLayout);
> }
>
> @Override
> protected void addQuestionText(FormEntryPrompt p) {
> return;
> }
>
> private void launchMap() {
> Intent i = null;
151c188,190
< addView(mViewButton);
---
> i = new Intent(getContext(), GeoPointMapActivity.class);
> } else {
> i = new Intent(getContext(), GeoPointActivity.class);
153c192,270
< addView(mAnswerDisplay);
---
> ((Activity) getContext()).startActivityForResult(i,
> FormEntryActivity.LOCATION_CAPTURE);
> mWaitingForData = true;
> }
> @Override
> public void onInAnimationDone() {
> addMapView();
> }
>
> protected void addMapView() {
> if (mUseMaps) {
> //addView(mViewButton);
> mMapView=(mFEA).getMapView();
> if (mMapView.getParent()!=null) {
> ((ViewGroup)(mMapView.getParent())).removeView(mMapView);
>
> }
>
> mMapView.setLayoutParams(rlp);
> mMapContainerLayout.addView(mMapView);
>
> View mapButtons=View.inflate(mFEA, R.layout.map_buttons_layout, null);
> mMapContainerLayout.addView(mapButtons);
>
> mLocationStatus=(TextView)findViewById(R.id.location_status);
>
>
>
> /*
> this.setLayoutParams(lp);
> LinearLayout p=this;
> while (p!=null) {
> if (p.getParent()!=null && p.getParent() instanceof LinearLayout) {
> p.setLayoutParams(lp);
> p.invalidate();
> p=(LinearLayout)(p.getParent());
>
> }
> else {
> break;
> }
> }
> if (p.getParent()!=null && p.getParent() instanceof RelativeLayout) {
> RelativeLayout r=(RelativeLayout)(p.getParent());
> RelativeLayout.LayoutParams lpr=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
> lpr.setMargins(0,0,0,0);
> p.setLayoutParams(lpr);
> r.invalidate();
> }
> */
> mMapView.setClickable(true);
> mMapView.setBuiltInZoomControls(true);
> mMapView.displayZoomControls(false);
> mMapView.setSatellite(false);
> mMapView.getController().setZoom(24);
> List<Overlay> overlays=mMapView.getOverlays();
> if (overlays.size()==0) {
> Log.d("GeoPointWidget","Creating Location Overlay (from constructor)");
> mFEA.createLocationOverlay();
> }
> mMapView.invalidate();
>
> mAcceptButton=(Button)findViewById(R.id.accept_location);
> //mAcceptButton.setEnabled(false);
> mAcceptButton.setText(R.string.cancel_location);
> mAcceptButton.setOnClickListener(new View.OnClickListener() {
> @Override
> public void onClick(View v) {
> acceptOrSkip();
> }
> });
>
>
> if (mFEA.getGeoPoint()!=null) onLocationChanged();
>
> mFEA.disableFling();
> }
> //addView(mAnswerDisplay);
>
155d271
<
163a280,284
>
> private void acceptOrSkip() {
> mFEA.enableFling();
> mFEA.showNextView();
> }
269a391,414
> }
> private String truncateFloat(float f) {
> return new DecimalFormat("#.##").format(f);
> }
> public void onLocationChanged() {
> //We need the mLocationStatus text view
> if (mMapView==null) return;
> if (mLocationStatus!=null)
> mLocationStatus.setText(getContext().getString(R.string.location_provider_accuracy,
> mFEA.getLocation().getProvider(), truncateFloat(mFEA.getLocation().getAccuracy())));
> if (mAcceptButton!=null) mAcceptButton.setText(R.string.accept_location);
> Log.d("GeoPointWidget","onLocationChanged. Overlays: "+(mMapView.getOverlays().size()));
> GeoPoint gp=mFEA.getGeoPoint();
> if (gp!=null) mMapView.getController().animateTo(mFEA.getGeoPoint());
> List<Overlay> overlays=mMapView.getOverlays();
> if (overlays.size()==0) {
> Log.d("GeoPointWidget","Creating Location Overlay");
> mFEA.createLocationOverlay();
> }
> Location location=mFEA.getLocation();
> if (location!=null) {
> setBinaryData(location.getLatitude() + " " + location.getLongitude() + " "
> + location.getAltitude() + " " + location.getAccuracy(), false);
> }
diff -r /media/DATA/lavoro/eclipse_workspace/ODK Collect/src/net/xxx/collect/android/widgets/ImageWidget.java /media/DATA/lavoro/xxx/backups/odk src embedded maps/net/xxx/collect/android/widgets/ImageWidget.java
330c330,335
< if (mBinaryName==null) {
---
>
> }
>
> @Override
> public void onInAnimationDone() {
> if (mBinaryName==null) {
diff -r /media/DATA/lavoro/eclipse_workspace/ODK Collect/src/net/xxx/collect/android/widgets/QuestionWidget.java /media/DATA/lavoro/xxx/backups/odk src embedded maps/net/xxx/collect/android/widgets/QuestionWidget.java
147a148,151
>
> public void onInAnimationDone() {
>
> }
回答1:
Generate the diff using "diff -ruN path1 path2", apply the patch using "patch -p{N} < patchfile", where N determines the prefix of the path to strip from the files in the diff. Just look at the patch & analyze the "diff" lines to see what should be stripped off. (See: man patch) . Before applying the patch, do use "patch --dry-run -p0 < patchfile" to make sure everything will be at least reasonably sane.
Edit: Note the different contents of a patch generated using normal diff
, unified diff (-u
) and context diff (-c
), and you'll see that the filename simply isn't included in 'normal' diff. The "diff" command is there, but the filename to patch is not. (Note also that the actual 'diff' output varies a bit from platform to platform, program to program, and patch
has to do a little bit of interpolation to determine the patch format, and even tries to guess if you've given it the wrong options).
$ diff -r -u a b
diff -r -u a/dir/file1 b/dir/file1
--- a/dir/file1 2012-08-02 18:27:30.050247358 -0700
+++ b/dir/file1 2012-08-02 18:27:27.190198620 -0700
@@ -1 +1 @@
-contents A
+contents B
$ diff -r -c a b
diff -r -c a/dir/file1 b/dir/file1
*** a/dir/file1 2012-08-02 18:27:30.050247358 -0700
--- b/dir/file1 2012-08-02 18:27:27.190198620 -0700
***************
*** 1 ****
! contents A
--- 1 ----
! contents B
$ diff -r a b
diff -r a/dir/file1 b/dir/file1
1c1
< contents A
---
> contents B
回答2:
I had this problem when doing:
patch <file_patch> <file_destination>
instead of:
patch <file_destination> <file_patch>
来源:https://stackoverflow.com/questions/11531693/patch-only-garbage-was-found-in-the-patch-input