diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py
index bca0d2b..e513ee6 100644
--- a/geopandas/geodataframe.py
+++ b/geopandas/geodataframe.py
@@ -118,6 +118,15 @@ class GeoDataFrame(GeoPandasBase, DataFrame):
         # allowed in that case
         # TODO do we want to raise / return normal DataFrame in this case?
         if geometry is None and "geometry" in self.columns:
+            # Check for multiple columns with name "geometry". If there are,
+            # self["geometry"] is a gdf and constructor gets recursively recalled
+            # by pandas internals trying to access this
+            if (self.columns == "geometry").sum() > 1:
+                raise ValueError(
+                    "GeoDataFrame does not support multiple columns "
+                    "using the geometry column name 'geometry'."
+                )
+
             # only if we have actual geometry values -> call set_geometry
             index = self.index
             try:
@@ -271,11 +280,17 @@ class GeoDataFrame(GeoPandasBase, DataFrame):
             raise ValueError("Must pass array with one dimension only.")
         else:
             try:
-                level = frame[col].values
+                level = frame[col]
             except KeyError:
                 raise ValueError("Unknown column %s" % col)
             except Exception:
                 raise
+            if isinstance(level, DataFrame):
+                raise ValueError(
+                    "GeoDataFrame does not support setting the geometry column where "
+                    "the column name is shared by multiple columns."
+                )
+
             if drop:
                 to_remove = col
                 geo_column_name = self._geometry_column_name
@@ -1395,6 +1410,13 @@ box': (2.0, 1.0, 2.0, 1.0)}], 'bbox': (1.0, 1.0, 2.0, 2.0)}
             for name in self._metadata:
                 object.__setattr__(self, name, getattr(other.objs[0], name, None))
 
+            if (self.columns == self._geometry_column_name).sum() > 1:
+                raise ValueError(
+                    "Concat operation has resulted in multiple columns using "
+                    f"the geometry column name '{self._geometry_column_name}'.\n"
+                    f"Please ensure this column from the first DataFrame is not "
+                    f"repeated."
+                )
         return self
 
     def dissolve(

diff --git a/geopandas/tests/test_geodataframe.py b/geopandas/tests/test_geodataframe.py
index 420274c..0b9e247 100644
--- a/geopandas/tests/test_geodataframe.py
+++ b/geopandas/tests/test_geodataframe.py
@@ -1008,6 +1008,24 @@ class TestConstructor:
         res = GeoDataFrame(data, geometry=geoms)
         assert_geoseries_equal(res.geometry, GeoSeries(geoms))
 
+    def test_repeat_geo_col(self):
+        df = pd.DataFrame(
+            [
+                {"geometry": Point(x, y), "geom": Point(x, y)}
+                for x, y in zip(range(3), range(3))
+            ],
+        )
+        # explicitly prevent construction of gdf with repeat geometry column names
+        # two columns called "geometry", geom col inferred
+        df2 = df.rename(columns={"geom": "geometry"})
+        with pytest.raises(ValueError):
+            GeoDataFrame(df2)
+        # ensure case is caught when custom geom column name is used
+        # two columns called "geom", geom col explicit
+        df3 = df.rename(columns={"geometry": "geom"})
+        with pytest.raises(ValueError):
+            GeoDataFrame(df3, geometry="geom")
+
 
 def test_geodataframe_crs():
     gdf = GeoDataFrame()
diff --git a/geopandas/tests/test_merge.py b/geopandas/tests/test_merge.py
index d003b11..a0495ab 100644
--- a/geopandas/tests/test_merge.py
+++ b/geopandas/tests/test_merge.py
@@ -1,4 +1,6 @@
 import pandas as pd
+import pytest
+from geopandas.testing import assert_geodataframe_equal
 
 from shapely.geometry import Point
 
@@ -48,6 +50,13 @@ class TestMerging:
         assert isinstance(res, GeoDataFrame)
         assert isinstance(res.geometry, GeoSeries)
         self._check_metadata(res)
+        exp = GeoDataFrame(pd.concat([pd.DataFrame(self.gdf), pd.DataFrame(self.gdf)]))
+        assert_geodataframe_equal(exp, res)
+        # check metadata comes from first gdf
+        res4 = pd.concat([self.gdf.set_crs("epsg:4326"), self.gdf], axis=0)
+        # Note: this behaviour potentially does not make sense. If geom cols are
+        # concatenated but have different CRS, then the CRS will be overridden.
+        self._check_metadata(res4, crs="epsg:4326")
 
         # series
         res = pd.concat([self.gdf.geometry, self.gdf.geometry])
@@ -63,3 +72,28 @@ class TestMerging:
         assert isinstance(res, GeoDataFrame)
         assert isinstance(res.geometry, GeoSeries)
         self._check_metadata(res)
+
+    def test_concat_axis1_multiple_geodataframes(self):
+        # https://github.com/geopandas/geopandas/issues/1230
+        # Expect that concat should fail gracefully if duplicate column names belonging
+        # to geometry columns are introduced.
+        expected_err = (
+            "GeoDataFrame does not support multiple columns using the geometry"
+            " column name 'geometry'"
+        )
+        with pytest.raises(ValueError, match=expected_err):
+            pd.concat([self.gdf, self.gdf], axis=1)
+
+        # Check case is handled if custom geometry column name is used
+        df2 = self.gdf.rename_geometry("geom")
+        expected_err2 = (
+            "Concat operation has resulted in multiple columns using the geometry "
+            "column name 'geom'."
+        )
+        with pytest.raises(ValueError, match=expected_err2):
+            pd.concat([df2, df2], axis=1)
+
+        # Check that two geometry columns is fine, if they have different names
+        res3 = pd.concat([df2.set_crs("epsg:4326"), self.gdf], axis=1)
+        # check metadata comes from first df
+        self._check_metadata(res3, geometry_column_name="geom", crs="epsg:4326")

BUG: pd.concat([..], axis=1) fails
This "works":

```
In [86]: geopandas.__version__
Out[86]: '0.5.1'

In [87]: countries = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))

In [89]: cities = geopandas.read_file(geopandas.datasets.get_path("naturalearth_cities"))

In [90]: pd.concat([cities, countries], axis=1) 
Out[90]: 
             name                                      geometry      pop_est      continent                      name iso_a3  gdp_md_est                                           geometry
0    Vatican City   POINT (12.45338654497177 41.90328217996012)     920938.0        Oceania                      Fiji    FJI      8374.0  (POLYGON ((180 -16.06713266364245, 180 -16.555...
1      San Marino     POINT (12.44177015780014 43.936095834768)   53950935.0         Africa                  Tanzania    TZA    150600.0  POLYGON ((33.90371119710453 -0.950000000000000...
2           Vaduz   POINT (9.516669472907267 47.13372377429357)     603253.0         Africa                 W. Sahara    ESH       906.5  POLYGON ((-8.665589565454809 27.65642588959236...
3      Luxembourg   POINT (6.130002806227083 49.61166037912108)   35623680.0  North America                    Canada    CAN   1674000.0  (POLYGON ((-122.84 49.00000000000011, -122.974...
4         Palikir   POINT (158.1499743237623 6.916643696007725)  326625791.0  North America  United States of America    USA  18560000.0  (POLYGON ((-122.84 49.00000000000011, -120 49....
..            ...                                           ...          ...            ...                       ...    ...         ...                                                ...
[202 rows x 8 columns]
```

But once you do something spatial with the resulting GeoDataFrame (anything that accesses the "geometry column"), things breaks (due to there being two columns with the "geometry" name).

In 0.6.0 this already started failing when doing the concat:

```
In [10]: pd.concat([cities, pd.DataFrame(countries)], axis=1)  
---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-10-e059be43b4e0> in <module>
----> 1 pd.concat([cities, pd.DataFrame(countries)], axis=1)

~/scipy/pandas/pandas/core/reshape/concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, sort, copy)
    253     )
    254 
--> 255     return op.get_result()
    256 
    257 

~/scipy/pandas/pandas/core/reshape/concat.py in get_result(self)
    474 
    475             cons = self.objs[0]._constructor
--> 476             return cons._from_axes(new_data, self.new_axes).__finalize__(
    477                 self, method="concat"
    478             )

~/scipy/pandas/pandas/core/generic.py in _from_axes(cls, data, axes, **kwargs)
    407         # for construction from BlockManager
    408         if isinstance(data, BlockManager):
--> 409             return cls(data, **kwargs)
    410         else:
    411             if cls._AXIS_REVERSED:

~/scipy/geopandas/geopandas/geodataframe.py in __init__(self, *args, **kwargs)
     74             index = self.index
     75             try:
---> 76                 self["geometry"] = _ensure_geometry(self["geometry"].values)
     77             except TypeError:
     78                 pass

~/scipy/geopandas/geopandas/geodataframe.py in __getitem__(self, key)
    554         GeoDataFrame.
    555         """
--> 556         result = super(GeoDataFrame, self).__getitem__(key)
    557         geo_col = self._geometry_column_name
    558         if isinstance(key, str) and key == geo_col:

~/scipy/pandas/pandas/core/frame.py in __getitem__(self, key)
   2693             indexer = np.where(indexer)[0]
   2694 
-> 2695         data = self.take(indexer, axis=1)
   2696 
   2697         if is_single_key:

~/scipy/pandas/pandas/core/generic.py in take(self, indices, axis, is_copy, **kwargs)
   3432             indices, axis=self._get_block_manager_axis(axis), verify=True
   3433         )
-> 3434         result = self._constructor(new_data).__finalize__(self)
   3435 
   3436         # Maybe set copy if we didn't actually change the index.

... last 4 frames repeated, from the frame below ...

~/scipy/geopandas/geopandas/geodataframe.py in __init__(self, *args, **kwargs)
     74             index = self.index
     75             try:
---> 76                 self["geometry"] = _ensure_geometry(self["geometry"].values)
     77             except TypeError:
     78                 pass

RecursionError: maximum recursion depth exceeded
```
```
geopandas/tests/test_merge.py::TestMerging::test_concat_axis1_multiple_geodataframes geopandas/tests/test_geodataframe.py::TestConstructor::test_repeat_geo_col
geopandas/tests/test_merge.py::TestMerging::test_merge geopandas/tests/test_merge.py::TestMerging::test_concat_axis1 geopandas/tests/test_geodataframe.py::TestConstructor::test_dict geopandas/tests/test_geodataframe.py::TestConstructor::test_no_geometries geopandas/tests/test_geodataframe.py::TestConstructor::test_column_ordering geopandas/tests/test_geodataframe.py::TestConstructor::test_overwrite_geometry geopandas/tests/test_geodataframe.py::TestConstructor::test_array geopandas/tests/test_geodataframe.py::TestConstructor::test_from_frame_specified_geometry geopandas/tests/test_geodataframe.py::TestConstructor::test_dict_specified_geometry geopandas/tests/test_geodataframe.py::TestConstructor::test_from_frame geopandas/tests/test_geodataframe.py::TestConstructor::test_dict_of_series geopandas/tests/test_geodataframe.py::TestConstructor::test_empty geopandas/tests/test_geodataframe.py::test_geodataframe_crs geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_keepna geopandas/tests/test_geodataframe.py::TestDataFrame::test_from_feature_collection geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_wkt geopandas/tests/test_geodataframe.py::TestDataFrame::test_df_init geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_only_geom_column geopandas/tests/test_geodataframe.py::TestDataFrame::test_copy geopandas/tests/test_geodataframe.py::TestDataFrame::test_geo_getitem geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_drop_id geopandas/tests/test_geodataframe.py::TestDataFrame::test_from_features geopandas/tests/test_geodataframe.py::TestDataFrame::test_set_geometry geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_wkb geopandas/tests/test_geodataframe.py::TestDataFrame::test_estimate_utm_crs geopandas/tests/test_geodataframe.py::TestDataFrame::test_set_geometry_col geopandas/tests/test_geodataframe.py::TestDataFrame::test_from_dict geopandas/tests/test_geodataframe.py::TestDataFrame::test_different_geo_colname geopandas/tests/test_geodataframe.py::TestDataFrame::test_set_geometry_series geopandas/tests/test_geodataframe.py::TestDataFrame::test_from_features_unaligned_properties geopandas/tests/test_geodataframe.py::TestDataFrame::test_dataframe_to_geodataframe geopandas/tests/test_geodataframe.py::TestDataFrame::test_geodataframe_iterfeatures geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_with_duplicate_columns geopandas/tests/test_geodataframe.py::TestDataFrame::test_rename_geometry geopandas/tests/test_geodataframe.py::TestDataFrame::test_geodataframe_geojson_no_bbox geopandas/tests/test_geodataframe.py::TestDataFrame::test_set_geometry_inplace geopandas/tests/test_geodataframe.py::TestDataFrame::test_bool_index geopandas/tests/test_geodataframe.py::TestDataFrame::test_geometry_property_errors geopandas/tests/test_geodataframe.py::TestDataFrame::test_geodataframe_geojson_bbox geopandas/tests/test_geodataframe.py::TestDataFrame::test_geometry_property geopandas/tests/test_geodataframe.py::TestDataFrame::test_from_features_geom_interface_feature geopandas/tests/test_geodataframe.py::TestDataFrame::test_getitem_no_geometry geopandas/tests/test_geodataframe.py::TestDataFrame::test_set_geometry_empty geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_drop_id_only_geom_column geopandas/tests/test_geodataframe.py::TestDataFrame::test_pickle_method geopandas/tests/test_geodataframe.py::TestDataFrame::test_coord_slice_points geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json geopandas/tests/test_geodataframe.py::TestDataFrame::test_geo_setitem geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_geom_col geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_bad_na geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_dropna geopandas/tests/test_geodataframe.py::TestDataFrame::test_to_json_na geopandas/tests/test_geodataframe.py::TestDataFrame::test_geodataframe_geointerface